ฟีเจอร์และ API ของ Android 8.1

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) อย่าลืมว่าการทำแอปเบาลงและมีประสิทธิภาพมากขึ้นจะเป็นประโยชน์ต่อผู้ชมทุกคน ไม่ว่าจะใช้อุปกรณ์ใดก็ตาม

Neural Networks API

Neural Networks API ให้การประมวลผลและการอนุมานที่รวดเร็วสําหรับเฟรมเวิร์กแมชชีนเลิร์นนิงในอุปกรณ์ เช่น TensorFlowLite ซึ่งเป็นไลบรารี ML แบบข้ามแพลตฟอร์มของ Google สําหรับอุปกรณ์เคลื่อนที่ รวมถึง Caffe2 และอื่นๆ ไปที่ repo โอเพนซอร์สของ TensorFlow Lite เพื่อดาวน์โหลดและดูเอกสาร TensorFlow Lite ทำงานร่วมกับ API โครงข่ายระบบประสาทเทียมเพื่อเรียกใช้โมเดลอย่างเช่น MobileNets Inception v3, และ ช่วยตอบได้อย่างมีประสิทธิภาพบนอุปกรณ์เคลื่อนที่

การอัปเดตเฟรมเวิร์กการป้อนข้อความอัตโนมัติ

Android 8.1 (API ระดับ 27) มีการปรับปรุงเฟรมเวิร์กการป้อนข้อความอัตโนมัติหลายอย่างที่คุณนำไปใช้ในแอปได้

BaseAdapter ชั้นเรียนในขณะนี้จะมี setAutofillOptions() ซึ่งช่วยให้คุณระบุการแสดงแทนสตริงของค่าในแอตทริบิวต์ อะแดปเตอร์ ซึ่งมีประโยชน์สำหรับไอคอนหมุน ซึ่งใช้สร้างค่าแบบไดนามิกในอะแดปเตอร์ ตัวอย่างเช่น คุณจะใช้เมธอด setAutofillOptions() เพื่อระบุสตริงได้ แสดงรายชื่อปีที่ผู้ใช้สามารถเลือกเป็นส่วนหนึ่งของ วันหมดอายุของบัตรเครดิต บริการป้อนข้อความอัตโนมัติใช้การแสดงสตริงได้ เพื่อกรอกข้อมูลพร็อพเพอร์ตี้ที่ต้องการข้อมูลนั้นอย่างเหมาะสม

นอกจากนี้ AutofillManager คลาสยังมีเมธอด notifyViewVisibilityChanged(View, int, boolean) ที่คุณสามารถเรียกใช้เพื่อแจ้งให้เฟรมเวิร์กทราบเกี่ยวกับการเปลี่ยนแปลงระดับการมองเห็นของมุมมองในโครงสร้างเสมือน นอกจากนี้ ยังมีวิธีการที่โอเวอร์โหลดสำหรับโครงสร้างที่ไม่ใช่แบบเสมือนจริงด้วย แต่ในกรณีทั่วไป คุณจะไม่จําเป็นต้องใช้โครงสร้างเสมือน แจ้งเฟรมเวิร์กอย่างชัดเจน เนื่องจากเมธอดถูกเรียกโดย View

นอกจากนี้ Android 8.1 ยังช่วยให้บริการป้อนข้อความอัตโนมัติปรับแต่งการช่วยเหลือในการบันทึก UI ได้มากขึ้นด้วยการเพิ่มการรองรับ CustomDescription and Validator ภายใน SaveInfo

คำอธิบายที่กำหนดเองมีประโยชน์ในการช่วยให้บริการป้อนข้อความอัตโนมัติอธิบายสิ่งที่ ได้รับการบันทึก เช่น เมื่อหน้าจอแสดงบัตรเครดิต แสดงโลโก้ธนาคารบัตรเครดิต ตัวเลข 4 หลักสุดท้ายของบัตรเครดิต และหมายเลขวันหมดอายุ ดูข้อมูลเพิ่มเติมได้ที่ CustomDescription ชั้นเรียน

Validator เพื่อหลีกเลี่ยงการแสดง UI การบันทึกการป้อนข้อความอัตโนมัติเมื่อโปรแกรมตรวจสอบ ไม่เป็นไปตามเงื่อนไข ดูข้อมูลเพิ่มเติมได้ที่คลาส Validator พร้อมกับคลาสย่อย LuhnChecksumValidator และ RegexValidator

การแจ้งเตือน

Android 8.1 มีการเปลี่ยนแปลงการแจ้งเตือนดังต่อไปนี้

  • ตอนนี้แอปจะส่งเสียงแจ้งเตือนได้เพียงครั้งเดียวต่อวินาที เสียงการแจ้งเตือนที่เกิน จะไม่รวมอยู่ในคิวและจะหายไป การเปลี่ยนแปลงนี้ไม่ส่งผลต่อลักษณะการทํางานอื่นๆ ของการแจ้งเตือนและข้อความการแจ้งเตือนจะยังคงแสดงตามที่คาดไว้
  • อุปกรณ์ Android ที่มี RAM ต่ำซึ่งแสดงผล true เมื่อเรียกใช้ ActivityManager.isLowRamDevice() ไม่รองรับ NotificationListenerService และ ConditionProviderService

การอัปเดต EditText

เริ่มต้นด้วย API ระดับ 27 เมธอด EditText.getText() จะแสดง Editable ก่อนหน้านี้ คำสั่งซื้อแสดงผล CharSequence การเปลี่ยนแปลงนี้ สามารถเข้ากันได้แบบย้อนหลัง เนื่องจาก Editable ใช้งาน CharSequence

อินเทอร์เฟซ Editable มีฟังก์ชันการทำงานเพิ่มเติมที่มีประโยชน์ ตัวอย่างเช่น เนื่องจาก Editable ใช้อินเทอร์เฟซ Spannable ด้วย คุณจึงใช้มาร์กอัปกับเนื้อหาภายในอินสแตนซ์ของ EditText ได้

การดำเนินการของ Google Safe Browsing แบบเป็นโปรแกรม

โดยการใช้ WebViewการใช้งาน 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:valu>e=&qu<ot;true">;< /
    /a>pplication
/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 ให้สิทธิ์เข้าถึงที่อธิบายไฟล์ ซึ่งสามารถแมปกับการอ่านและเขียนได้ ซึ่งดีมาก วิธีการแชร์ข้อมูลจำนวนมาก ข้อมูลระหว่างแอปต่างๆ หรือระหว่างหลายๆ กระบวนการภายในแอปเดียวได้

API WallpaperColors

Android 8.1 (API ระดับ 27) ช่วยให้วอลเปเปอร์เคลื่อนไหวแสดงสีได้ ลงใน UI ของระบบ ซึ่งทำได้โดยสร้าง WallpaperColors จากบิตแมป ถอนออกได้ หรือใช้ 3 สีที่คุณเลือกด้วยตนเอง คุณยังเรียกข้อมูลสีนี้ได้ด้วย

หากต้องการสร้างออบเจ็กต์ WallpaperColors ให้ทําอย่างใดอย่างหนึ่งต่อไปนี้

  • วิธีสร้าง WallpaperColors โดยใช้สี 3 สี สร้างอินสแตนซ์ของ WallpaperColors โดยผ่านชั้นประถม มัธยม และสีตติยภูมิ สีหลักต้องไม่เป็นค่า Null
  • วิธีสร้าง WallpaperColors จากบิตแมป เรียกใช้ fromBitmap() โดยการส่งแหล่งที่มาของบิตแมปเป็นพารามิเตอร์
  • หากต้องการสร้างออบเจ็กต์ WallpaperColors จาก Drawable ให้เรียกใช้เมธอด fromDrawable() โดยส่งแหล่งที่มาของ Drawable เป็นพารามิเตอร์

หากต้องการเรียกข้อมูลรายละเอียดสีหลัก สีรอง หรือสีรองลงมาจากวอลเปเปอร์ ให้เรียกใช้เมธอดต่อไปนี้

  • 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:GCM
    • KeyGenerator:AES
    • KeyGenerator:DESEDE
    • KeyGenerator:HMACMD5
    • KeyGenerator:HMACSHA1
    • KeyGenerator:HMACSHA224
    • KeyGenerator:HMACSHA256
    • KeyGenerator:HMACSHA384
    • KeyGenerator:HMACSHA512
    • SecretKeyFactory:DESEDE
    • Signature:NONEWITHECDSA
  • Cipher.getParameters().getParameterSpec(IvParameterSpec.class) ไม่ทำงานกับอัลกอริทึมที่ GCM อีกต่อไป ให้ใช้ getParameterSpec(GCMParameterSpec.class)
  • คลาส Conscrypt ภายในจำนวนมากที่เชื่อมโยงกับ TLS ได้รับการรีแฟกทอริง ตั้งแต่ปี นักพัฒนาซอฟต์แวร์ก็เข้าถึงภาพสะท้อนเหล่านี้ ได้กลายเป็นส่วนหนึ่งของ รองรับการใช้งานก่อนหน้านี้ แต่รายละเอียดบางอย่างมีการเปลี่ยนแปลง ตัวอย่างเช่น ก่อนหน้านี้ซ็อกเก็ตเป็นประเภท OpenSSLSocketImpl แต่ตอนนี้เป็นประเภท ConscryptFileDescriptorSocket หรือ ConscryptEngineSocket ซึ่งทั้ง 2 ประเภทนี้ขยายมาจาก OpenSSLSocketImpl
  • วิธีการ SSLSession ที่ใช้เพื่อแสดงข้อยกเว้น IllegalArgumentException เมื่อส่งผ่านรีเฟอเรนซ์ Null ตอนนี้จะแสดงข้อยกเว้น NullPointerException
  • RSA KeyFactory ไม่อนุญาตให้สร้างคีย์จากอาร์เรย์ไบต์ที่ใหญ่กว่าคีย์ที่เข้ารหัสอีกต่อไป โทรหา generatePrivate() และ generatePublic() ที่มีฟิลด์ KeySpec โดยที่โครงสร้างคีย์ไม่เติมเต็ม บัฟเฟอร์ทั้งหมดจะแสดงผลเป็น InvalidKeySpecException
  • เมื่อซ็อคเก็ตที่ปิดไปขัดจังหวะการอ่านซ็อกเก็ต ระบบจะใช้ Conscrypt เพื่อส่งคืน -1 จากการอ่าน การอ่านตอนนี้จะแสดง SocketException
  • ชุดใบรับรองรูท CA มีการเปลี่ยนแปลง โดยส่วนใหญ่เป็นการนําใบรับรองที่ล้าสมัยจํานวนมากออก รวมถึงนําใบรับรองรูทของ WoSign และ StartCom ออกด้วย ดูข้อมูลเพิ่มเติมเกี่ยวกับการตัดสินใจนี้ได้ที่บล็อกโพสต์การรักษาความปลอดภัยของ Google เรื่องการเลิกเชื่อถือใบรับรอง WoSign และ StartCom อย่างสมบูรณ์