Android 8.1 (ระดับ API 27) เปิดตัวฟีเจอร์และความสามารถใหม่ๆ มากมายสำหรับผู้ใช้และนักพัฒนาแอป เอกสารนี้จะเน้นย้ำถึงฟีเจอร์ใหม่ๆ สำหรับนักพัฒนาแอป
Android Oreo (รุ่น Go)
Android Go เป็นโครงการริเริ่มของเราในการเพิ่มประสิทธิภาพประสบการณ์การใช้งาน Android สำหรับ ผู้คนหลายพันล้านคนทั่วโลกที่กำลังจะเข้าสู่โลกออนไลน์ ตั้งแต่ Android 8.1 เป็นต้นไป เราจะทำให้ Android เป็นแพลตฟอร์มที่ยอดเยี่ยมสำหรับอุปกรณ์ระดับเริ่มต้น ฟีเจอร์ในการกำหนดค่า Android Oreo (รุ่น Go) มีดังนี้
- การเพิ่มประสิทธิภาพหน่วยความจำ ปรับปรุงการใช้หน่วยความจำในแพลตฟอร์มเพื่อให้มั่นใจว่าแอปจะทำงานได้อย่างมีประสิทธิภาพในอุปกรณ์ที่มี RAM 1 GB หรือน้อยกว่า
- ตัวเลือกการกำหนดเป้าหมายที่ยืดหยุ่น ค่าคงที่ของฟีเจอร์ฮาร์ดแวร์ใหม่ เพื่อให้คุณกำหนดเป้าหมายการเผยแพร่แอปไปยังอุปกรณ์ที่มี RAM ปกติหรือต่ำผ่าน Google Play ได้
- Google Play แม้ว่าแอปทั้งหมดจะพร้อมให้บริการในอุปกรณ์ที่ใช้ Android Oreo (รุ่น Go) แต่ Google Play จะให้การมองเห็นแก่แอปที่นักพัฒนาแอปปรับแต่งมาโดยเฉพาะ เพื่อมอบประสบการณ์การใช้งานที่ยอดเยี่ยมแก่ผู้ใช้หลายพันล้านคนตาม หลักเกณฑ์สำหรับแอปที่สร้างขึ้นเพื่อผู้ใช้หลายพันล้านคน
เราได้อัปเดต หลักเกณฑ์การสร้างแอปสำหรับผู้ใช้หลายพันล้านคน พร้อมคำแนะนำเพิ่มเติมเกี่ยวกับวิธี เพิ่มประสิทธิภาพแอปสำหรับอุปกรณ์ที่ใช้ Android Oreo (รุ่น Go) สำหรับนักพัฒนาแอปส่วนใหญ่ การเพิ่มประสิทธิภาพ APK ที่มีอยู่หรือการใช้ ฟีเจอร์ APK หลายรายการของ Google Play เพื่อกำหนดเป้าหมาย APK เวอร์ชันหนึ่งไปยังอุปกรณ์ที่มี RAM ต่ำ เป็นวิธีที่ดีที่สุดในการเตรียมพร้อมสำหรับอุปกรณ์ที่ใช้ Android Oreo (Go Edition) โปรดทราบว่าการทำให้แอป เบาและมีประสิทธิภาพมากขึ้นจะเป็นประโยชน์ต่อผู้ชมทั้งหมด ไม่ว่าจะใช้อุปกรณ์ใดก็ตาม
Neural Networks API
Neural Networks API ช่วยให้การคำนวณและการอนุมานสำหรับเฟรมเวิร์กแมชชีนเลิร์นนิงในอุปกรณ์ เช่น TensorFlow Lite ซึ่งเป็นไลบรารี ML แบบข้ามแพลตฟอร์มของ Google สำหรับอุปกรณ์เคลื่อนที่ รวมถึง Caffe2 และอื่นๆ ทำงานได้เร็วขึ้น ไปที่ที่เก็บโอเพนซอร์สของ TensorFlow Lite เพื่อดาวน์โหลดและดูเอกสาร TensorFlow Lite ทำงานร่วมกับ Neural Networks API เพื่อเรียกใช้โมเดลต่างๆ เช่น MobileNets Inception v3 และ การตอบกลับอัจฉริยะอย่างมีประสิทธิภาพในอุปกรณ์เคลื่อนที่
การอัปเดตเฟรมเวิร์กการป้อนข้อความอัตโนมัติ
Android 8.1 (ระดับ API 27) มีการปรับปรุงหลายอย่างใน Autofill Framework ที่คุณสามารถนำไปใช้ในแอปได้
ตอนนี้BaseAdapter
คลาสมีเมธอด setAutofillOptions()
ซึ่งช่วยให้คุณระบุการแสดงสตริงของค่าใน
อแดปเตอร์ได้ ซึ่งมีประโยชน์สำหรับตัวควบคุม spinner
ที่สร้างค่าในอะแดปเตอร์แบบไดนามิก เช่น คุณสามารถใช้เมธอด setAutofillOptions() เพื่อระบุการแสดงสตริง
ของรายการปีที่ผู้ใช้เลือกได้เป็นส่วนหนึ่งของ
วันหมดอายุของบัตรเครดิต บริการป้อนข้อความอัตโนมัติสามารถใช้การแสดงสตริง
เพื่อกรอกข้อมูลในมุมมองที่ต้องใช้ข้อมูลได้อย่างเหมาะสม
นอกจากนี้ AutofillManager
คลาสยังมีnotifyViewVisibilityChanged(View, int, boolean)เมธอด
ที่คุณเรียกใช้เพื่อแจ้งเฟรมเวิร์กเกี่ยวกับการเปลี่ยนแปลงระดับการมองเห็นของ
มุมมองในโครงสร้างเสมือนได้ นอกจากนี้ ยังมีการโอเวอร์โหลดของเมธอดสำหรับโครงสร้างที่ไม่ใช่
เสมือนด้วย อย่างไรก็ตาม โครงสร้างที่ไม่ใช่เสมือนมักไม่จำเป็นต้องให้คุณ
แจ้งเฟรมเวิร์กอย่างชัดเจน เนื่องจากView
คลาสเรียกใช้เมธอดนี้อยู่แล้ว
Android 8.1 ยังช่วยให้บริการป้อนข้อความอัตโนมัติปรับแต่งความสามารถในการแสดง UI การบันทึกได้มากขึ้น
โดยเพิ่มการรองรับ CustomDescription
and Validator
ภายใน SaveInfo
คำอธิบายที่กำหนดเองมีประโยชน์ในการช่วยให้บริการป้อนข้อความอัตโนมัติชี้แจงสิ่งที่
กำลังบันทึก ตัวอย่างเช่น เมื่อหน้าจอมีบัตรเครดิต ก็อาจแสดงโลโก้ของธนาคารที่ออกบัตรเครดิต ตัวเลข 4 หลักสุดท้ายของหมายเลขบัตรเครดิต
และหมายเลขวันหมดอายุ ดูข้อมูลเพิ่มเติมได้ที่
CustomDescription
ชั้นเรียน
Validator
ออบเจ็กต์ใช้เพื่อหลีกเลี่ยงการแสดง UI การบันทึกการป้อนข้อความอัตโนมัติเมื่อไม่เป็นไปตามเงื่อนไขของ Validator
ดูข้อมูลเพิ่มเติมได้ที่คลาส
Validator พร้อมด้วยคลาสย่อย
LuhnChecksumValidator และ RegexValidator
การแจ้งเตือน
Android 8.1 มีการเปลี่ยนแปลงการแจ้งเตือนดังนี้
- ตอนนี้แอปจะส่งเสียงแจ้งเตือนได้เพียงครั้งเดียวต่อวินาที ระบบจะไม่จัดคิวและจะทิ้งเสียงการแจ้งเตือนที่เกินอัตรานี้ การเปลี่ยนแปลงนี้ไม่มีผลต่อลักษณะการทำงานของการแจ้งเตือนในด้านอื่นๆ และข้อความแจ้งเตือนจะยังคงโพสต์ตามที่คาดไว้
-
NotificationListenerServiceและConditionProviderServiceไม่รองรับในอุปกรณ์ Android ที่มี RAM ต่ำ ซึ่งจะแสดงtrueเมื่อมีการเรียกใช้ActivityManager.isLowRamDevice()
การอัปเดต EditText
ตั้งแต่ระดับ API 27 เป็นต้นไป เมธอด EditText.getText() จะแสดง Editable ก่อนหน้านี้ จะแสดง CharSequence การเปลี่ยนแปลงนี้เข้ากันได้แบบย้อนหลัง เนื่องจาก Editable ใช้ CharSequence
Editable อินเทอร์เฟซมีฟังก์ชันเพิ่มเติมที่มีประโยชน์
ตัวอย่างเช่น เนื่องจาก Editable ยัง
ใช้Spannable อินเทอร์เฟซด้วย คุณจึงใช้มาร์กอัปกับ
เนื้อหาภายในอินสแตนซ์ของ EditText ได้
การดำเนินการของ Google Safe Browsing แบบเป็นโปรแกรม
การใช้
WebViewการติดตั้งใช้งาน ของ Google Safe Browsing API จะช่วยให้แอป
ตรวจหาได้เมื่ออินสแตนซ์ของ WebView พยายามไปยัง
URL ที่ Google จัดประเภทว่าเป็นภัยคุกคามที่ทราบ โดยค่าเริ่มต้น
WebView จะแสดงโฆษณาคั่นระหว่างหน้าที่เตือนผู้ใช้ถึงภัยคุกคามที่ทราบ
หน้าจอนี้จะให้ตัวเลือกแก่ผู้ใช้ในการโหลด URL ต่อไปหรือกลับไปยัง
หน้าก่อนหน้าที่ปลอดภัย
ใน Android 8.1 คุณสามารถกำหนดโดยใช้โปรแกรมว่าแอปจะตอบสนองต่อภัยคุกคามที่ทราบได้อย่างไร
- คุณควบคุมได้ว่าแอปจะรายงานภัยคุกคามที่ทราบไปยัง Google Safe Browsing หรือไม่
- คุณตั้งค่าให้แอปดำเนินการบางอย่างโดยอัตโนมัติได้ เช่น กลับไปที่โหมดปลอดภัย ทุกครั้งที่แอปพบ URL ที่ Google Safe Browsing จัดประเภทเป็นภัยคุกคามที่ทราบ
หมายเหตุ: เพื่อการปกป้องที่ดีที่สุดจากภัยคุกคามที่ทราบแล้ว ให้รอจนกว่าคุณจะเริ่มต้นใช้งาน Google Safe Browsing ก่อนที่จะเรียกใช้เมธอด loadUrl() ของออบเจ็กต์ WebView
ข้อมูลโค้ดต่อไปนี้แสดงวิธีสั่งให้อินสแตนซ์ของ
WebView ในแอปกลับไปที่โหมดปลอดภัยเสมอหลังจากพบภัยคุกคามที่รู้จัก
AndroidManifest.xml
<manifest>
<application>
...
<meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
android:value="true" />
</application>
</manifest>MyWebActivity.java
Kotlin
private var superSafeWebView: WebView? = null private var safeBrowsingIsInitialized: Boolean = false // ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) superSafeWebView = WebView(this).apply { webViewClient = MyWebViewClient() safeBrowsingIsInitialized = false startSafeBrowsing(this@SafeBrowsingActivity, { success -> safeBrowsingIsInitialized = true if (!success) { Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!") } }) } }
Java
private WebView superSafeWebView; private boolean safeBrowsingIsInitialized; // ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); superSafeWebView = new WebView(this); superSafeWebView.setWebViewClient(new MyWebViewClient()); safeBrowsingIsInitialized = false; superSafeWebView.startSafeBrowsing(this, new ValueCallback<Boolean>() { @Override public void onReceiveValue(Boolean success) { safeBrowsingIsInitialized = true; if (!success) { Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!"); } } }); }
MyWebViewClient.java
Kotlin
class MyWebViewClient : WebViewClient() { // Automatically go "back to safety" when attempting to load a website that // Safe Browsing has identified as a known threat. An instance of WebView // calls this method only after Safe Browsing is initialized, so there's no // conditional logic needed here. override fun onSafeBrowsingHit( view: WebView, request: WebResourceRequest, threatType: Int, callback: SafeBrowsingResponse ) { // The "true" argument indicates that your app reports incidents like // this one to Safe Browsing. callback.backToSafety(true) Toast.makeText(view.context, "Unsafe web page blocked.", Toast.LENGTH_LONG).show() } }
Java
public class MyWebViewClient extends WebViewClient { // Automatically go "back to safety" when attempting to load a website that // Safe Browsing has identified as a known threat. An instance of WebView // calls this method only after Safe Browsing is initialized, so there's no // conditional logic needed here. @Override public void onSafeBrowsingHit(WebView view, WebResourceRequest request, int threatType, SafeBrowsingResponse callback) { // The "true" argument indicates that your app reports incidents like // this one to Safe Browsing. callback.backToSafety(true); Toast.makeText(view.getContext(), "Unsafe web page blocked.", Toast.LENGTH_LONG).show(); } }
โปรแกรมแยกภาพปกวิดีโอ
คลาส MediaMetadataRetriever มีเมธอดใหม่ getScaledFrameAtTime() ซึ่งจะค้นหา
เฟรมที่อยู่ใกล้กับตำแหน่งเวลาที่ระบุและแสดงผลบิตแมปที่มีสัดส่วน
เดียวกันกับเฟรมต้นฉบับ แต่ปรับขนาดให้พอดีกับสี่เหลี่ยมผืนผ้าที่มีความกว้างและความสูงที่ระบุ ซึ่งมีประโยชน์สำหรับการสร้างภาพปกจากวิดีโอ
เราขอแนะนำให้ใช้วิธีนี้แทน getFrameAtTime() ซึ่งอาจทำให้หน่วยความจำหมด
เนื่องจากจะแสดงผลบิตแมปที่มีความละเอียดเท่ากับวิดีโอต้นฉบับ ตัวอย่างเช่น เฟรมจากวิดีโอ 4K จะเป็นบิตแมปขนาด 16 MB ซึ่งใหญ่กว่าขนาดที่คุณต้องการสำหรับภาพปกวิดีโอมาก
Shared Memory API
Android 8.1 (ระดับ API 27) เปิดตัว
SharedMemory
API ใหม่ คลาสนี้ช่วยให้คุณสร้าง แมป และจัดการอินสแตนซ์ที่ไม่ระบุตัวตน
SharedMemory
ได้ คุณตั้งค่าการป้องกันหน่วยความจำ
ในออบเจ็กต์
SharedMemory
สำหรับการอ่านและ/หรือเขียน และเนื่องจากออบเจ็กต์
SharedMemory
เป็น Parcelable คุณจึงส่งไปยังกระบวนการอื่นผ่าน AIDL ได้อย่างง่ายดาย
SharedMemory
API ทำงานร่วมกับ
ASharedMemory ใน NDK
ASharedMemory ให้สิทธิ์เข้าถึง
ตัวอธิบายไฟล์ ซึ่งสามารถแมปเพื่ออ่านและเขียนได้ ซึ่งเป็นวิธีที่ยอดเยี่ยม
ในการแชร์ข้อมูลจำนวนมาก
ระหว่างแอปหรือระหว่างกระบวนการหลายอย่างภายในแอปเดียว
WallpaperColors API
Android 8.1 (ระดับ API 27) อนุญาตให้วอลเปเปอร์เคลื่อนไหวของคุณให้ข้อมูลสีแก่ UI ของระบบได้ คุณทำได้โดยสร้างWallpaperColors
ออบเจ็กต์จากบิตแมป, Drawable หรือโดยใช้สี 3 สีที่เลือกด้วยตนเอง
นอกจากนี้ คุณยังดึงข้อมูลสีนี้ได้ด้วย
หากต้องการสร้างWallpaperColors
ออบเจ็กต์ ให้ทำอย่างใดอย่างหนึ่งต่อไปนี้
- หากต้องการสร้าง
WallpaperColorsออบเจ็กต์โดยใช้ 3 สี ให้สร้างอินสแตนซ์ของคลาสWallpaperColorsโดยส่งสีหลัก สีรอง และสีเสริม ต้องระบุสีหลัก - หากต้องการสร้างออบเจ็กต์
WallpaperColorsจากบิตแมป ให้เรียกใช้เมธอดfromBitmap()โดยส่งแหล่งที่มาของบิตแมปเป็นพารามิเตอร์ - หากต้องการสร้างออบเจ็กต์
WallpaperColorsจาก Drawable ให้เรียกใช้เมธอดfromDrawable()โดยส่งแหล่งที่มาของ Drawable เป็นพารามิเตอร์
หากต้องการดึงรายละเอียดสีหลัก สีรอง หรือสีระดับที่ 3 จากวอลเปเปอร์ ให้เรียกใช้เมธอดต่อไปนี้
getPrimaryColor()จะแสดงสีที่แสดงถึงวอลเปเปอร์ได้ดีที่สุดgetSecondaryColor()แสดงสีที่โดดเด่นที่สุดเป็นอันดับ 2 ของวอลเปเปอร์getTertiaryColor()เมธอดจะแสดงสีที่โดดเด่นเป็นอันดับ 3 ของวอลเปเปอร์
หากต้องการแจ้งระบบเกี่ยวกับการเปลี่ยนแปลงสีที่สำคัญในวอลเปเปอร์เคลื่อนไหว ให้เรียกใช้เมธอด notifyColorsChanged()
เมธอดนี้จะทริกเกอร์เหตุการณ์onComputeColors()วงจร
ซึ่งคุณจะมีโอกาสระบุออบเจ็กต์ WallpaperColors
ใหม่
หากต้องการเพิ่ม Listener สำหรับการเปลี่ยนสี ให้เรียกใช้เมธอด addOnColorsChangedListener() คุณยังเรียกใช้เมธอด getWallpaperColors()
เพื่อดึงสีหลักของวอลเปเปอร์ได้ด้วย
การอัปเดตลายนิ้วมือ
คลาส FingerprintManager ได้
เปิดตัวรหัสข้อผิดพลาดต่อไปนี้
-
FINGERPRINT_ERROR_LOCKOUT_PERMANENT– ผู้ใช้พยายามปลดล็อกอุปกรณ์โดยใช้เครื่องอ่านลายนิ้วมือหลายครั้งเกินไป -
FINGERPRINT_ERROR_VENDOR- เกิดข้อผิดพลาดเกี่ยวกับเครื่องอ่านลายนิ้วมือที่เจาะจงผู้ให้บริการ
การอัปเดตวิทยาการเข้ารหัส
เราได้ทำการเปลี่ยนแปลงด้านการเข้ารหัสหลายอย่างใน Android 8.1 ดังนี้
- เราได้ติดตั้งใช้งานอัลกอริทึมใหม่ใน Conscrypt ระบบจะใช้การติดตั้งใช้งาน Conscrypt
ก่อนการติดตั้งใช้งาน Bouncy Castle
ที่มีอยู่ อัลกอริทึมใหม่มีดังนี้
AlgorithmParameters:GCMKeyGenerator:AESKeyGenerator:DESEDEKeyGenerator:HMACMD5KeyGenerator:HMACSHA1KeyGenerator:HMACSHA224KeyGenerator:HMACSHA256KeyGenerator:HMACSHA384KeyGenerator:HMACSHA512SecretKeyFactory:DESEDESignature:NONEWITHECDSA
Cipher.getParameters().getParameterSpec(IvParameterSpec.class)ใช้ไม่ได้กับอัลกอริทึมที่ใช้ GCM อีกต่อไป ให้ใช้getParameterSpec(GCMParameterSpec.class)แทน- เราได้ปรับโครงสร้างคลาส Conscrypt ภายในหลายคลาสที่เชื่อมโยงกับ TLS เนื่องจากบางครั้งนักพัฒนาแอปเข้าถึงฟีเจอร์เหล่านี้โดยอ้อม เราจึงคง Shim ไว้เพื่อรองรับการใช้งานก่อนหน้านี้ แต่รายละเอียดบางอย่างมีการเปลี่ยนแปลง เช่น ก่อนหน้านี้ซ็อกเก็ตมีประเภทเป็น
OpenSSLSocketImplแต่ตอนนี้มีประเภทเป็นConscryptFileDescriptorSocketหรือConscryptEngineSocketซึ่งทั้ง 2 ประเภทนี้ขยายOpenSSLSocketImpl SSLSessionวิธีการที่ใช้ในการส่งข้อยกเว้นIllegalArgumentExceptionเมื่อส่งการอ้างอิงที่ค่าเป็น Null ตอนนี้จะส่งข้อยกเว้นNullPointerException- RSA
KeyFactoryไม่อนุญาตให้สร้างคีย์จากอาร์เรย์ไบต์ที่มีขนาดใหญ่กว่าคีย์ที่เข้ารหัสอีกต่อไป การโทรไปยังgeneratePrivate()และgeneratePublic()ที่ให้KeySpecซึ่งโครงสร้างคีย์ไม่ได้เติม บัฟเฟอร์ทั้งหมดจะส่งผลให้เกิดInvalidKeySpecException - เมื่อการอ่านซ็อกเก็ตถูกขัดจังหวะเนื่องจากซ็อกเก็ตปิดอยู่ Conscrypt จะ
แสดงผล -1 จากการอ่าน การอ่านในตอนนี้จะทำให้เกิดข้อผิดพลาด
SocketException - เราได้เปลี่ยนแปลงชุดใบรับรอง CA รูท โดยส่วนใหญ่เป็นการนำใบรับรองจำนวนมากที่ล้าสมัยออก รวมถึงนำใบรับรองรูทสำหรับ WoSign และ StartCom ออกด้วย ดูข้อมูลเพิ่มเติมเกี่ยวกับการตัดสินใจนี้ได้ที่บล็อกโพสต์การรักษาความปลอดภัยของ Google การ นำความน่าเชื่อถือในใบรับรองของ WoSign และ StartCom ออกในที่สุด