ویژگی‌ها و میاناهای برنامه‌سازی کاربردی Android 8.1

‫Android 8.1 (میانای برنامه‌سازی کاربردی سطح ۲۷) مجموعه‌ای از ویژگی‌ها و قابلیت‌های جدید را برای کاربران و توسعه‌دهندگان معرفی می‌کند. این سند موارد جدید برای توسعه‌دهندگان را برجسته می‌کند.

Android Oreo (نسخه Go)

Android Go ابتکار ما برای بهینه‌سازی تجربه Android برای میلیاردها نفری است که در سراسر جهان به فضای آنلاین می‌آیند. با شروع از Android 8.1، درحال تبدیل Android به پلاتفرمی عالی برای دستگاه‌های سطح پایین هستیم. ویژگی‌های پیکربندی Android Oreo (نسخه Go) شامل موارد زیر می‌شود:

  • بهینه‌سازی‌های حافظه. بهبود استفاده از حافظه در سراسر پلاتفرم برای اطمینان از اینکه برنامه‌ها می‌توانند به‌طور کارآمد در دستگاه‌های دارای ۱ گیگابایت یا کمتر حافظه دسترسی تصادفی اجرا شوند.
  • گزینه‌های هدف‌یابی انعطاف‌پذیر. ثابت‌های ویژگی سخت‌افزاری جدیدی که به شما امکان می‌دهد توزیع برنامه‌هایتان را ازطریق Google Play برای دستگاه‌های معمولی یا دستگاه‌های با RAM پایین هدف‌یابی کنید.
  • Google Play.اگرچه همه برنامه‌ها در دستگاه‌های دارای Android Oreo (نسخه Go) دردسترس خواهند بود، Google Play برنامه‌هایی را که توسعه‌دهندگان به‌طور ویژه برای ارائه تجربه عالی به میلیاردها نفر با رعایت دستورالعمل‌های «ساختن برای میلیاردها نفر» بهینه‌سازی کرده‌اند، نمایان می‌کند.

رهنمودهای «ساختن برای میلیاردها کاربر» را با راهنمایی‌های بیشتر درباره نحوه بهینه‌سازی برنامه برای دستگاه‌های دارای Android Oreo (نسخه Go) به‌روز کرده‌ایم. برای اکثر توسعه‌دهندگان، بهینه‌سازی فایل APK موجود یا استفاده از ویژگی «چندین APK» در Google Play برای هدف‌یابی نسخه APK خود برای دستگاه‌های دارای حافظه دسترسی تصادفی پایین بهترین راه برای آماده شدن برای دستگاه‌های دارای Android Oreo (نسخه Go) است. به‌یاد داشته باشید که سبک‌تر و کارآمدتر کردن برنامه شما به نفع همه مخاطبان شما است، صرف‌نظر از دستگاه.

میانای برنامه‌سازی کاربردی شبکه‌های عصبی

«میانای برنامه‌سازی کاربردی شبکه‌های عصبی» محاسبات و استنباط شتاب‌یافته‌ای برای چارچوب‌های یادگیری ماشین درون‌دستگاهی مانند TensorFlow Lite—کتابخانه ML چندپلاتفرمی Google برای تلفن همراه— و همچنین Caffe2 و غیره ارائه می‌دهد. برای بارگیری‌ها و اسناد، به مخزن متن‌باز TensorFlow Lite مراجعه کنید. ‫TensorFlow Lite با «میانای برنامه‌سازی کاربردی شبکه‌های عصبی» کار می‌کند تا مدل‌هایی مثل MobileNets، Inception v3، و پاسخ هوشمند را به‌طور کارآمد در دستگاه همراهتان اجرا کند.

به‌روزرسانی‌های چارچوب تکمیل خودکار

‫Android 8.1 (سطح API 27) چندین بهبود در «چارچوب تکمیل خودکار» ارائه می‌دهد که می‌توانید در برنامه‌هایتان بگنجانید.

کلاس BaseAdapter اکنون شامل روش setAutofillOptions() است که به شما امکان می‌دهد نمایش‌های رشته‌ای مقادیر را در آداپتور ارائه دهید. این برای کنترل‌های گردونه که مقادیر را به‌صورت پویا در آداپتورهایشان تولید می‌کنند مفید است. برای مثال، می‌توانید از روش setAutofillOptions() برای ارائه نمایش رشته‌ای از فهرست سال‌هایی که کاربران می‌توانند به‌عنوان بخشی از تاریخ انقضای کارت اعتباری انتخاب کنند استفاده کنید. سرویس‌های تکمیل خودکار می‌توانند از نمایش رشته‌ای برای تکمیل مناسب نماهایی که به داده‌ها نیاز دارند استفاده کنند.

علاوه‌براین، AutofillManager کلاس شامل notifyViewVisibilityChanged(View, int, boolean) متدی است که می‌توانید آن را فراخوانی کنید تا چارچوب را از تغییرات نمایان بودن نمای در ساختار مجازی مطلع کنید. همچنین سربار روش برای ساختارهای غیرمجازی وجود دارد. بااین‌حال، ساختارهای غیرمجازی معمولاً نیازی ندارند که چارچوب را به‌طور صریح مطلع کنید زیرا روش قبلاً توسط View کلاس فراخوانی شده است.

‫Android 8.1 همچنین با افزودن پشتیبانی از CustomDescription and Validator در SaveInfo، به «سرویس‌های تکمیل خودکار» امکان بیشتری برای سفارشی‌سازی کردن ظاهر کاربرپسند ذخیره می‌دهد.

توضیحات سفارشی برای کمک به سرویس تکمیل خودکار در روشن کردن آنچه ذخیره می‌شود مفید است؛ برای مثال، وقتی صفحه حاوی کارت اعتباری است، می‌تواند نشان‌واره بانک کارت اعتباری، چهار رقم آخر شماره کارت اعتباری، و شماره انقضای آن را نمایش دهد. برای کسب اطلاعات بیشتر، کلاس CustomDescription را ببینید.

از Validator هدف‌ها برای جلوگیری از نمایش واسط کاربر ذخیره تکمیل خودکار وقتی شرط «درستی‌سنج» برآورده نمی‌شود استفاده می‌شود. برای کسب اطلاعات بیشتر، کلاس Validator را به‌همراه زیرکلاس‌های آن، LuhnChecksumValidator و RegexValidator، ببینید.

اعلان‌ها

‫Android 8.1 شامل تغییرات زیر در اعلان‌ها است:

  • اکنون برنامه‌ها فقط می‌توانند هر ثانیه یک‌بار صدای هشدار اعلان پخش کنند. صداهای هشداری که از این نرخ فراتر می‌روند در صف قرار نمی‌گیرند و ازدست می‌روند. این تغییر بر دیگر جنبه‌های رفتار اعلان تأثیر نمی‌گذارد و پیام‌های اعلان همچنان طبق انتظار پست می‌شوند.
  • NotificationListenerService و ConditionProviderService در دستگاه‌های Android با حافظه دسترسی تصادفی کم که هنگام فراخوانی ActivityManager.isLowRamDevice()، مقدار true را برمی‌گردانند پشتیبانی نمی‌شوند.

به‌روزرسانی EditText

از سطح میانای برنامه‌سازی کاربردی ۲۷، روش EditText.getText() مقدار Editable را برمی‌گرداند؛ قبلاً مقدار CharSequence را برمی‌گرداند. این تغییر سازگار با نسخه قدیمی است، زیرا Editable CharSequence را پیاده‌سازی می‌کند.

واسط Editable عملکرد اضافی ارزشمندی ارائه می‌دهد. برای مثال، چون Editable نیز رابط Spannable را پیاده‌سازی می‌کند، می‌توانید نشانه را به محتوای درون نمونه EditText اعمال کنید.

کنش‌های «مرور ایمن» برنامه‌ریزی‌شده

بااستفاده از پیاده‌سازی WebView «میانای برنامه‌سازی کاربردی مرور ایمن»، برنامه شما می‌تواند وقتی نمونه‌ای از WebView تلاش می‌کند به نشانی وب که Google آن را به‌عنوان تهدید شناخته‌شده طبقه‌بندی کرده است پیمایش کند، آن را تشخیص دهد. به‌طور پیش‌فرض، WebView بینابینی‌ای نشان می‌دهد که به کاربران درباره تهدید شناخته‌شده هشدار می‌دهد. این صفحه به کاربران امکان می‌دهد که نشانی وب را بار کنند یا به صفحه قبلی که ایمن است برگردند.

در Android 8.1، می‌توانید به‌صورت برنامه‌ریزی‌شده تعریف کنید که برنامه شما چگونه به تهدید شناخته‌شده پاسخ دهد:

  • می‌توانید کنترل کنید که برنامه شما تهدیدهای شناخته‌شده را به «مرور ایمن» گزارش کند یا نه.
  • می‌توانید برنامه‌تان را طوری تنظیم کنید که هر بار با نشانی وبی مواجه شد که «مرور ایمن» آن را به‌عنوان تهدید شناخته‌شده طبقه‌بندی می‌کند، کنش خاصی را به‌طور خودکار انجام دهد، مثلاً به حالت ایمن برگردد.

توجه: برای محافظت بهینه دربرابر تهدیدات شناخته‌شده، پیش‌از فراخوانی کردن روش loadUrl() شیء WebView، منتظر بمانید تا «مرور ایمن» را مقداردهی اولیه کنید.

تکه‌کدهای زیر نشان می‌دهد چگونه می‌توانید به نمونه‌های برنامه خود از WebView دستور دهید که پس‌از مواجهه با تهدید شناخته‌شده همیشه به حالت ایمن برگردند:

AndroidManifest.xml

<manifest>
    <application>
        ...
        <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
                   android:value="true" />
    </application>
</manifest>

MyWebActivity.java

کاتلین

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!")
            }
        })
    }
}

جاوا

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

کاتلین

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()
    }
}

جاوا

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 یک بیت‌مپ ۱۶ مگابایتی خواهد بود که بسیار بزرگ‌تر از چیزی است که برای یک تصویر ریزعکس نیاز دارید.

میانای برنامه‌سازی کاربردی حافظه مشترک

‫Android 8.1 (سطح API 27) یک SharedMemory API جدید معرفی می‌کند. این کلاس به شما اجازه می‌دهد نمونه‌ای ناشناس SharedMemory ایجاد، نگاشت، و مدیریت کنید. حفاظت حافظه را روی SharedMemory شیء برای خواندن و/یا نوشتن تنظیم می‌کنید، و ازآنجایی‌که SharedMemory شیء Parcelable است، می‌توانید به‌راحتی آن را ازطریق AIDL به فرایند دیگری منتقل کنید.

میانای برنامه‌سازی کاربردی SharedMemory با ASharedMemory در NDK تعامل‌پذیر است. ‫ASharedMemory دسترسی به توصیف‌گر فایل را فراهم می‌کند که سپس می‌تواند برای خواندن و نوشتن نگاشت شود. روش بسیار خوبی برای هم‌رسانی حجم زیادی از داده بین برنامه‌ها یا بین چندین فرایند در یک برنامه است.

WallpaperColors API

‫Android 8.1 (سطح API 27) به کاغذدیواری پویا اجازه می‌دهد اطلاعات رنگ را به واسط کاربر سیستم ارائه دهد. این کار را با ایجاد یک WallpaperColors شیء از یک بیت‌مپ، یک طراحی، یا بااستفاده از سه رنگ انتخاب‌شده دستی انجام می‌دهید. همچنین می‌توانید این اطلاعات رنگ را بازیابی کنید.

برای ایجاد WallpaperColors شیء، یکی از کارهای زیر را انجام دهید:

  • برای ایجاد WallpaperColors شیء بااستفاده از سه رنگ، نمونه‌ای از کلاس WallpaperColors را با ارسال رنگ اصلی، رنگ فرعی، و رنگ سوم ایجاد کنید. رنگ اصلی نباید خالی باشد.
  • برای ایجاد یک WallpaperColors شیء از یک بیت‌مپ، روش fromBitmap() را با ارسال منبع بیت‌مپ به‌عنوان پارامتر فراخوانی کنید.
  • برای ایجاد WallpaperColors شیء از طراحی‌کردنی، با ارسال منبع طراحی‌کردنی به‌عنوان پارامتر، fromDrawable() روش را فراخوانی کنید.

برای بازیابی جزئیات رنگ اصلی، ثانویه، یا ثالث از کاغذدیواری، روش‌های زیر را فراخوانی کنید:

  • getPrimaryColor() رنگی را برمی‌گرداند که ازنظر بصری بیشترین نماینده کاغذدیواری است.
  • getSecondaryColor() دومین رنگ برجسته کاغذدیواری را برمی‌گرداند.
  • getTertiaryColor() روش سومین رنگ غالب کاغذدیواری را برمی‌گرداند.

برای اطلاع دادن به سیستم درباره هرگونه تغییر رنگ قابل‌توجه در کاغذدیواری زنده، روش notifyColorsChanged() را فراخوانی کنید. این روش رویداد چرخه حیات onComputeColors() را راه‌اندازی می‌کند که در آن فرصت دارید شیء WallpaperColors جدیدی ارائه دهید.

برای افزودن شنونده برای تغییرات رنگ، می‌توانید روش 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 هستند، که هر دو OpenSSLSocketImpl را گسترش می‌دهند.
  • ‫SSLSession روش استفاده‌شده برای پرتاب کردن ‫IllegalArgumentException هنگام عبور از مرجع تهی، اکنون ‫NullPointerException را پرتاب می‌کند.
  • ‫RSA KeyFactory دیگر اجازه تولید کلید از آرایه‌های بایتی بزرگ‌تر از کلید کدبندی‌شده را نمی‌دهد. تماس با generatePrivate() و generatePublic() که KeySpec ارائه می‌دهند و ساختار کلید کل بافر را پر نمی‌کند منجر به InvalidKeySpecException می‌شود.
  • وقتی خواندن سوکت با بسته شدن سوکت قطع می‌شود، Conscrypt از مقدار -۱ برای خواندن استفاده می‌کند. اکنون خواندن SocketException را پرتاب می‌کند.
  • مجموعه گواهینامه‌های CA ریشه تغییر کرده است، که بیشتر شامل حذف تعداد زیادی گواهینامه منسوخ است، اما گواهینامه‌های ریشه WoSign و StartCom نیز حذف شده‌اند. برای کسب اطلاعات بیشتر درباره این تصمیم، پست وبلاگ «امنیت Google» با عنوان حذف نهایی اعتماد به گواهینامه‌های WoSign و StartCom را ببینید.