"Only fullscreen opaque activities can request orientation "問題再分析

前言

最近在升級targetsdkversion,我負責了一部分的升級適配工做,後面會找時間對Android升級targetsdkversion的相關工做作一個比較深刻的總結。可是今天我想把一個問題單獨拎出來講一說。那就是網上盛傳的 Android8.0 "Only fullscreen opaque activities can request orientation "問題。這個問題從被你們發現,到如今已經快一年半了,解決方案都很全,之因此叫在分析,是由於這裏面還有些問題一直沒有被解釋清楚,昨天在作這個適配的時候也有些困擾,所以在這裏作一個簡短而全面的分析。java

問題起因

咱們先來講說這個問題的由來,最早在網上有人爆出,若是開發者把targetsdkversion調成27及以上,並且項目中的Activity主題設爲透明,而又指定了activity屏幕的方向的話,在Android8.0的手機上會直接拋出RunRuntimeException異常,而且打印的錯誤信息裏面會有這段話:"Only fullscreen opaque activities can request orientation "android

接着就有人指出這個是Android開發人員在開發Android8.0的時候的一次提交的代碼形成的問題。點擊傳送門git

從上述提交中,咱們可以看到開發人員意在阻止非全屏的activity影響屏幕的方向。而根據代碼追蹤到的代碼片斷大概是這裏:github

if (ActivityInfo.isFixedOrientation(requestedOrientation) // 是否鎖定了屏幕方向
    && !fullscreen // 不是全屏
    && appInfo.targetSdkVersion >= O) { // targetsdkversion版本是Android8及以上
    throw new IllegalStateException("Only fullscreen activities can request orientation");
}

複製代碼

而是不是全屏的判斷依據是如下幾個主題屬性:bash

public static boolean isTranslucentOrFloating(TypedArray attributes) { 
    final boolean isTranslucent = attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent, false); 
    final boolean isSwipeToDismiss = !attributes.hasValue( com.android.internal.R.styleable.Window_windowIsTranslucent) 
                                     && attributes.getBoolean( com.android.internal.R.styleable.Window_windowSwipeToDismiss, false); 
    final boolean isFloating = attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating, false);  
    return isFloating || isTranslucent || isSwipeToDismiss;    
}

複製代碼

問題到這裏看起來已經講清楚了,若是咱們設置了以上幾個主題,而且鎖定了屏幕方向,那麼在Android8.0的手機上系統會直接拋出異常。app

解決方案

咱們說說解決方法:ui

  • targetsdkversion下降到26及如下
  • 針對項目中的activity作一次檢查,避免指定透明主題的activity同時又指定了方向

基本上全部的解決方法本質上都是基於這兩種思路。好了,問題解決了。基本上網上關於相關問題的討論到這裏就結束了,好比下面這幾篇文章和討論:google

java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation spa

Only fullscreen activities can request orientation?一個搞笑的坑!3d

Kaola Mobile Team's Blog: Android O 適配詳細指南

固然,既然有了解決方案,因此通常分析到這裏也是能夠理解的。

未解釋的問題

但是當我看到上面這些文章或問答,內心仍是有一些其餘的疑問沒有被解答:

  • 按照上面的分析,在targetsdkversion>=26的時候,在Android8.0手機上應該都有異常,但實際上targetsdkversion=26的時候是OK的,只有升級到27及以上纔會崩

  • Android8之後真的解決了這個問題?

關於第一個問題,我繼續查看了Android8.0的源碼,以及它的提交記錄發如今這個提交不久以後,Android開發人員又有了新的提交,在sdk爲26時,放開了限制。

Allow for SDK 26 Activities to specify orientation when not fullscreen

因此當咱們設置的targetsdkversion<=26的時候沒有出現這個問題。只有在大於26的狀況下,這個異常出現。

第二個問題,在Android8.1.0的第一個release版本中確實去掉了相關的代碼,這個在Android8.1.0的release版本的提交紀錄裏可以看得出來 傳送門

總結

從這個問題的產生和解決過程來看,確實能夠說是Android系統開發人員的「手誤」了。可是說實話我很難想象會出現這樣的幺蛾子,竟然直接拋出異常。難道他們不知道不少開發者都會在Activity裏指定透明主題和固定方向?並且提交了這種代碼以後,在Android8.0系統更新說明裏竟然也沒有提到。唉,好吧。

相關文章
相關標籤/搜索