android7.0多窗口適配方案,你值得擁有

首先大致說一下android7.0改動的地方
Android N 這次的新特性包括多窗口的支持、通知欄支持直接回復消息、對部分廣播的後臺限制、網絡數據節省開關等,並不多,也有很多翻譯文章已經介紹。
這裏主要分享對 Android N 的適配大家可能要注意什麼。

還記得 6.0 對 Apache Http 庫的廢除導致的應用崩潰嗎?
還記得 6.0 中 MAC id 始終返回爲空導致的唯一 id 混合生成算法大幅失效嗎?
1. Android 中 Java 的實現向 OpenJDK 8 遷移
            Android 是站在 Linux 和 Java 肩膀上快速成長的,在運行時依賴 Oracle JDK,早在 2010 年甲骨文就起訴谷歌侵權 Java。在 N 中 Google 採用 OpenJDK 8 作爲 Java 的實現,在 Java 實現上的一些差別可能導致應用出問題。如:
          (1) ArrayList 實現中的私有屬性 array 被移除,反射使用該屬性的需要注意下。
          (2) 隨機數種子調用可能出錯
               Crypto 安全提供商在 OpenJDK 中不提供,而它在大家調用 SecureRandom.setSeed() 設置隨機種子時會用到,OpenJDK 中需要通過 SecretKeySpec 去直接加載原始密鑰或者使用真正的密鑰導出函數。
           有了解 OpenJDK 8 與 Oracle JDK 更多實現差別的歡迎留言。
           (1) 記得 2014 年 InfoQ 大會上 Oracle 的人介紹 Java 8 的特性,當時還在想 Android 現在依賴 JDK6.0 什麼時候才能到 8,現在終於等到了這一天,可惜不是你..
            (2) Kotlin 還有機會嗎?
2. JNI 中不允許調用非公有 API
           JNI 中不允許調用非公有 API,由於命名空間的變化,在 Android N 上運行會崩潰,需要切換到對應公有 API。
3. “老人機的適配”
            Android N 允許用戶設置顯示密度,有點像老人機模式。需要測試 App 在 sw320dp 密度下顯示是否正常,及配置變更後應用是否會有異常。
4. 後臺優化——三個廣播被禁止監聽或發送
           (1) CONNECTIVITY_CHANGE 廣播
                 對 targetVersion 設置爲 Android N 的 App,在後臺時不再能接收到 CONNECTIVITY_CHANGE 廣播,前臺不影響。
           (2) ACTION_NEW_PICTURE 和 ACTION_NEW_VIDEO 廣播
                 所有運行在 Android N 上的 App 不能發送或是接收新增圖片(ACTION_NEW_PICTURE)和新增視頻(ACTION_NEW_VIDEO) 的廣播。
5. 權限改動
           (1) GET_ACCOUNTS 權限被廢棄
                對 targetVersion 設置爲 Android N 的 App,GET_ACCOUNTS 權限被廢棄。
           (2) 增加 ACTION_OPEN_EXTERNAL_DIRECTORY 權限
這個感覺就是對部存儲設備寫權限的保護,需要用戶同意,說不定以後就慢慢廢棄 WRITE_EXTERNAL_STORAGE 權限了。
6. 更嚴格的 Doze 模式
            大家知道在 Android 6.0 中,在手機關屏且靜止時,Doze 模式通過推遲 CPU 和網絡操作延長底池壽命。而 Android N 則在手機關屏時就會一定程度限制 CPU 和網絡操作,進入 Doze 模式一段時間後進一步限制 WakeLock、Alarm、GPS 和 Wi-Fi 掃描等,做好迎接休眠狀態下更多功能受限導致的 bug 吧,哈哈。
7. 自帶 ICU4J 庫的子集
更方便 App 的全球化了
其實Android原生6.0也有自帶分屏.
          1. root
          2. 用RE文件管理器打開
system/build.prop找到ro.build.type這一行, 把=號後面的user改成userdebug,保存後重啓. 
          3. 重啓後,在系統設置進入開發者選項.
          4. 找到“多窗口模式”,激活功能即可.
在7.0版本時我們如何去實現多窗口呢?

給wm 應用配置分屏模式
在清單文件的 或 節點中設置該屬性,啓用或禁用多窗口顯示:

//設置爲true ,該activity支持分屏,默認爲true
android:resizeableActivity="true"

AndroidManifest中的佈局屬性
對於 Android N,<layout> 清單文件元素支持以下幾種屬性,這些屬性影響 Activity 在多窗口模式中的行爲,我們先看看下面的代碼.


<activity android:name=".MyActivity">
    <layout android:defaultHeight="500dp"
          android:defaultWidth="600dp"
          android:gravity="top|end"
          android:minimalSize="450dp" />
</activity>

這些佈局屬性會對多窗口帶來什麼影響呢?看看下面.
android:defaultWidth
以自由形狀模式啓動時 Activity 的默認寬度。
android:defaultHeight
以自由形狀模式啓動時 Activity 的默認高度。
android:gravity
以自由形狀模式啓動時 Activity 的初始位置。
android:minimalSize
分屏和自由形狀模式中 Activity 的最小高度和最小寬度。 如果用戶在分屏模式中移動分界線,使 Activity 尺寸低於指定的最小值,系統會將 Activity 裁剪爲用戶請求的尺寸。
例如,以下節點顯示瞭如何指定 Activity 在自由形狀模式中顯示時 Activity 的默認大小、位置和最小尺寸:

不同的配置下,效果會不一樣

    1. 如何設置禁止分屏.
      在AndroidManifest中配置UnresizableActivity的unresizable屬性.
      在這添加FLAG_ACTIVITY_NEW_TASK 標籤開啓新的任務棧,是爲了避免其繼承根activity的屬性,比如在根activity設置了尺寸大小的話,其不設置標籤屬性會被繼承.
Intent intent = new Intent(this, UnresizableActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

清單xml中配置unresizable屬性.

<activity
android:name="com.android.multiwindowplayground.activities.UnresizableActivity"
android:resizeableActivity="false"
android:taskAffinity="" />

    1. 設置以最小尺寸方式開啓分屏
      在AndroidManifest中配置MinimumSizeActivity的默認尺寸,最小尺寸,
 startActivity(new Intent(this, MinimumSizeActivity.class));

清單xml中配置unresizable屬性.

   <activity
            android:name="com.android.multiwindowplayground.activities.MinimumSizeActivity"
            android:launchMode="singleInstance"
            android:taskAffinity="">
            <layout
                android:defaultHeight="500dp"
                android:defaultWidth="750dp"
                android:gravity="top|end"
                android:minimalWidth="500dp"
                android:minimalHeight="500dp" />
        </activity>

    1. AndroidManifest 配置Configuration的參數會有什影響?
      activity中AndroidManifest 配置Configuration的參數,會影響到分屏.
<activity
        android:name=".CustomConfigurationChangeActivity"
        android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
        android:launchMode="singleInstance"
        android:taskAffinity=""/>

如果上面配置的參數有所變化,我們可以在onConfigurationChanged()方法中監聽到.
如下:

//重寫Activity中的onConfigurationChanged方法
@Override   
public void onConfigurationChanged(Configuration newConfig) {   
if(newConfig.orientation==Configuration.ORIENTATION_PORTRAIT)   {      
  //TODO 豎屏,需要處理的事情
}   

if(newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE)   {   
//TODO 橫屏,需要處理的事情
}   

   super.onConfigurationChanged(newConfig);   
}  

注意: 可能會監聽不了參數的變化,別忘記加上權限
<uses-permission Android:name="android.permission.CHANGE_CONFIGURATION"></uses-permission>

如何處理設備配置帶來的運行變化

有些設備配置可能會在運行時發生變化(例如屏幕方向、鍵盤可用性及語言)。 發生這種變化時,Android 會重啓正在運行的 Activity(先後調用 onDestroy()onCreate())。重啓行爲旨在通過利用與新設備配置匹配的備用資源自動重新加載您的應用,來幫助它適應新配置。

首先這個變化的過程是這樣的,如果你沒有在activity的屬性中配置’android:configChanges=”keyboardHidden| orientation’那麼默認是會走橫豎屏的,也就是說會走,銷燬Activity->創建Activity.

由於重啓整個Activity,如果數據量比較大的情況下,用戶體驗會十分差(例如網絡請求,複雜View的繪製,動畫的渲染等),所以解決這種體驗我們可以通過下面兩種方式:
- 通過onSaveInstanceState()onRestoreInstanceState()保存變動前的對象.
Android 會在銷燬 Activity 之前調用 onSaveInstanceState(),以便您保存有關應用狀態的數據。 然後,您可以在 onCreate() 或 onRestoreInstanceState() 期間恢復 Activity 狀態。

  • 通過`android:configChanges=”keyboardHidden| orientation’禁止橫豎屏切換.
    阻止系統在某些配置變更期間重啓 Activity,但要在配置確實發生變化時接收回調(具體回調上面有代碼),這樣,您就能夠根據需要手動更新 Activity。

多窗口的生命週期

除了知道上面的不同的配置下,效果會不一樣之外,我們是不是還要注意一個問題,我們知道Activity的橫豎屏會影響它的生命週期,那麼對於多窗口來說,是否也會有這樣的影響呢?

下面是Goodle官方的說明.

在多窗口模式中,在指定時間只有最近與用戶交互過的 Activity 爲活動狀態。 該 Activity 將被視爲頂級 Activity。 所有其他 Activity 雖然可見,但均處於暫停狀態。 但是,這些已暫停但可見的 Activity 在系統中享有比不可見 Activity 更高的優先級。 如果用戶與其中一個暫停的 Activity 交互,該 Activity 將恢復,而之前的頂級 Activity 將暫停。

注:在多窗口模式中,用戶仍可以看到處於暫停狀態的應用。 應用在暫停狀態下可能仍需要繼續其操作。 例如,處於暫停模式但可見的視頻播放應用應繼續顯示視頻。 因此,我們建議播放視頻的 Activity 不要暫停其 onPause() 處理程序中的視頻。 應暫停 onStop() 中的視頻,並恢復onStart() 中的視頻播放。

也就是說多窗口模式不會更改Activity的生命週期,但是在對一些需要使用到onPause()方法的爲了更好體驗,需要做小變動.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章