解決Android 應(yīng)用targetSdkVersion小于24(Android N)運(yùn)行在高版本設(shè)備無(wú)法全屏的BUG

前言

進(jìn)行公司車(chē)機(jī)設(shè)備開(kāi)發(fā)時(shí)挽拔,由于屏幕比例比較特殊(1920x720)英融,導(dǎo)致部分應(yīng)用顯示時(shí)左側(cè)和底部有很大的黑邊,使用dumpsys分析黑邊的View摩骨,移除后發(fā)現(xiàn)仍存在屁置,后確定為低版本默認(rèn)比例問(wèn)題焊夸,耗費(fèi)了幾個(gè)小時(shí),記錄下這個(gè)問(wèn)題蓝角。

出現(xiàn)問(wèn)題的條件:

  1. Android 應(yīng)用:targetSdkVersion < 24 (Android N)阱穗;
  2. 設(shè)備的分辨率寬高比大于1.861.86為Android低版本最大寬高比);
  3. Android 應(yīng)用的AndroidManifest.xml內(nèi)未設(shè)置android:resizeableActivity="true"屬性使鹅;

問(wèn)題解決方案

問(wèn)題根據(jù)不同的情況有不同的解決方式

  1. 若擁有應(yīng)用源碼揪阶,則可以直接將targetSdkVersion設(shè)置為大于等于24即可;
  2. 若擁有應(yīng)用源碼患朱,但不能修改targetSdkVersion版本鲁僚,那么就在
    應(yīng)用的AndroidManifest.xml內(nèi)設(shè)置android:resizeableActivity="true"屬性;
  3. 若擁有應(yīng)用源碼裁厅,但不能修改targetSdkVersion版本冰沙,但compileSdkVersion=26時(shí),
    可以嘗試在的AndroidManifest.xml內(nèi)設(shè)置android:maxAspectRatio=""="寬高比"屬性执虹;
  4. 若沒(méi)有應(yīng)用源碼拓挥,則需要嘗試修改系統(tǒng)層來(lái)達(dá)到適配的作用,具體修改見(jiàn)如下代碼:

系統(tǒng)層修改

/frameworks/base/core/java/android/content/pm/PackageParser.java
PackageParser在解析APKAndroidManifest.xml文件時(shí)声畏,有如下代碼:

public class PackageParser {
    ....
    private static final float DEFAULT_PRE_O_MAX_ASPECT_RATIO = 1.86f;
    ....
    private boolean parseBaseApplication(Package owner, Resources res,
            XmlResourceParser parser, int flags, String[] outError)
            throws XmlPullParserException, IOException {
        final ApplicationInfo ai = owner.applicationInfo;
        final String pkgName = owner.applicationInfo.packageName;
        
        TypedArray sa = res.obtainAttributes(parser,
                com.android.internal.R.styleable.AndroidManifestApplication);
        ....
        
        // 這里會(huì)去判斷xml內(nèi)是否有設(shè)置android:resizeableActivity屬性
        if (sa.hasValueOrEmpty(R.styleable.AndroidManifestApplication_resizeableActivity)) {
            if (sa.getBoolean(R.styleable.AndroidManifestApplication_resizeableActivity, true)) {
                // 設(shè)置該標(biāo)志位后撞叽,應(yīng)用的Activity可調(diào)整大小
                ai.privateFlags |= PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE;
            } else {
                // 設(shè)置該標(biāo)志位后姻成,應(yīng)用的Activity不可調(diào)整大小
                ai.privateFlags |= PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE;
            }
        } else if (owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
            // 若應(yīng)用未設(shè)置android:resizeableActivity屬性,且其targetSdkVersion >= Android N (24)
            // 設(shè)置該標(biāo)志位后愿棋,應(yīng)用的Activity可調(diào)整大小
            ai.privateFlags |= PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
-       }
+        }else {
+            ai.privateFlags |= PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE;
+        }
      
    }
    
}

根據(jù)以上代碼可以看到科展,默認(rèn)情況下沒(méi)有對(duì)未設(shè)置android:resizeableActivity屬性,且targetSdkVersion < 24的應(yīng)用不會(huì)設(shè)置其Activity可調(diào)整大小糠雨,所以我們需要為這種情況加上對(duì)應(yīng)的配置才睹,即添加上述代碼中的相應(yīng)內(nèi)容。修改后編譯進(jìn)設(shè)備甘邀,即可看到應(yīng)用全屏顯示了琅攘。

問(wèn)題分析

除了上面分析到的沒(méi)有Activity可調(diào)整大小標(biāo)志位導(dǎo)致的無(wú)法全屏問(wèn)題,還有一個(gè)是關(guān)于默認(rèn)最大寬高比(DEFAULT_PRE_O_MAX_ASPECT_RATIO)的問(wèn)題松邪,通過(guò)修改該值也可以實(shí)現(xiàn)應(yīng)用的全屏坞琴,不過(guò)有時(shí)候屏幕比例變化較大時(shí)該值可能要經(jīng)常改動(dòng),有點(diǎn)麻煩逗抑。下面主要是從源碼來(lái)分析下該值是如何起作用的剧辐。
/frameworks/base/core/java/android/content/pm/PackageParser.java

public class PackageParser {
    ....
    private static final float DEFAULT_PRE_O_MAX_ASPECT_RATIO = 1.86f;
    ....    
    private void setMaxAspectRatio(Package owner) {
        // 對(duì)于 O 之前的應(yīng)用程序默認(rèn)為 (1.86) 16.7:9 縱橫比,對(duì)于 O 及更高版本則未設(shè)置邮府。
        float maxAspectRatio = owner.applicationInfo.targetSdkVersion < O
                ? DEFAULT_PRE_O_MAX_ASPECT_RATIO : 0;

        if (owner.applicationInfo.maxAspectRatio != 0) {
            // 如果應(yīng)用設(shè)置了android:maxAspectRatio 屬性值荧关,則使用應(yīng)用程序所配置的最大寬高比。
            maxAspectRatio = owner.applicationInfo.maxAspectRatio;
        } else if (owner.mAppMetaData != null
                && owner.mAppMetaData.containsKey(METADATA_MAX_ASPECT_RATIO)) {
            // 未設(shè)置則設(shè)置為默認(rèn)的1.86
            maxAspectRatio = owner.mAppMetaData.getFloat(METADATA_MAX_ASPECT_RATIO, maxAspectRatio);
        }

        for (Activity activity : owner.activities) {
            // If the max aspect ratio for the activity has already been set, skip.
            if (activity.hasMaxAspectRatio()) {
                continue;
            }

            // 這里可以獲取activity設(shè)置的maxAspectRatio屬性褂傀,若應(yīng)用和activity都設(shè)置了忍啤,則以activity的優(yōu)先
            final float activityAspectRatio = activity.metaData != null
                    ? activity.metaData.getFloat(METADATA_MAX_ASPECT_RATIO, maxAspectRatio)
                    : maxAspectRatio;
            // 將最大寬高比設(shè)置給activity
            activity.setMaxAspectRatio(activityAspectRatio);
        }
    }
}

以上就是為何應(yīng)用無(wú)法全屏顯示的原因,以及另外一種修改為何也能生效的原因仙辟。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末同波,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子欺嗤,更是在濱河造成了極大的恐慌参萄,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件煎饼,死亡現(xiàn)場(chǎng)離奇詭異讹挎,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)吆玖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)筒溃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人沾乘,你說(shuō)我怎么就攤上這事怜奖。” “怎么了翅阵?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵歪玲,是天一觀的道長(zhǎng)迁央。 經(jīng)常有香客問(wèn)我,道長(zhǎng)滥崩,這世上最難降的妖魔是什么岖圈? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮钙皮,結(jié)果婚禮上蜂科,老公的妹妹穿的比我還像新娘。我一直安慰自己短条,他們只是感情好导匣,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著茸时,像睡著了一般贡定。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上屹蚊,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天厕氨,我揣著相機(jī)與錄音进每,去河邊找鬼汹粤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛田晚,可吹牛的內(nèi)容都是我干的嘱兼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼贤徒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼芹壕!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起接奈,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤踢涌,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后序宦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體睁壁,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年互捌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了潘明。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡秕噪,死狀恐怖钳降,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情腌巾,我是刑警寧澤遂填,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布铲觉,位于F島的核電站,受9級(jí)特大地震影響吓坚,放射性物質(zhì)發(fā)生泄漏备燃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一凌唬、第九天 我趴在偏房一處隱蔽的房頂上張望并齐。 院中可真熱鬧,春花似錦客税、人聲如沸况褪。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)测垛。三九已至,卻和暖如春秧均,著一層夾襖步出監(jiān)牢的瞬間食侮,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工目胡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锯七,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓誉己,卻偏偏與公主長(zhǎng)得像眉尸,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子巨双,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容