Android N獲取屏幕高度的問題

獲取屏幕高度的代碼

int getScreenHeight(Activity context) {
    WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
    DisplayMetrics metrics = new DisplayMetrics();
    wm.getDefaultDisplay().getMetrics(metrics);
    return metrics.heightPixels;
} 

問題現(xiàn)象

在Android N 7.0(SDK 24)上當(dāng),Activity進(jìn)入過分屏模式再退出后,使用上面的代碼去獲取屏幕高度,得到的值是真正的屏幕高度減去狀態(tài)欄的高度。然而在Android 7.1(SDK 25) 上,確沒有這個(gè)問題,猜測是谷歌的BUG,在7.1上已經(jīng)得到了修正。同時(shí)出問題的時(shí)候,傳入的context是Activity,但是當(dāng)我傳入的是ApplicationContext時(shí),返回的屏幕高度又是正確的,這就無語了。

問題原因

通過調(diào)試Android SDK 24和25的框架代碼,發(fā)現(xiàn)出現(xiàn)問題的原因是,SDK 24的ActivityThread的performConfigurationChanged方法configuration沒有正確地更新,但是SDK25做了修正。下面直接給出導(dǎo)致這個(gè)問題的框架代碼:
Android 7.0

public final class ActivityThread {
    ...
    private void performConfigurationChanged(...) {
        ...
        boolean shouldChangeConfig = false;
        if ((activity == null) || (activity.mCurrentConfig == null)) {
            shouldChangeConfig = true;
        } else {
            // If the new config is the same as the config this Activity
            // is already running with then don't bother calling
            // onConfigurationChanged
            int diff = activity.mCurrentConfig.diff(newConfig);
            if (diff != 0) {
                shouldChangeConfig = true;
            }
        }
        ...
}

Android 7.1

public final class ActivityThread {
    ...
    private void performConfigurationChanged(...) {
        ...
        boolean shouldChangeConfig = false;
        if ((activity == null) || (activity.mCurrentConfig == null)) {
            shouldChangeConfig = true;
        } else {
            // If the new config is the same as the config this Activity is already
            // running with and the override config also didn't change, then don't
            // bother calling onConfigurationChanged.
            int diff = activity.mCurrentConfig.diff(newConfig);
            if (diff != 0 || !mResourcesManager.isSameResourcesOverrideConfig(activityToken, amOverrideConfig)) {
                // Always send the task-level config changes. For system-level configuration, if
                // this activity doesn't handle any of the config changes, then don't bother
                // calling onConfigurationChanged as we're going to destroy it.
                if (!mUpdatingSystemConfig
                        || (~activity.mActivityInfo.getRealConfigChanged() & diff) == 0
                        || !reportToActivity) {
                    shouldChangeConfig = true;
                }
            }
        }
        ...
}

比較這兩塊代碼,可以發(fā)現(xiàn) SDK25增加了!mResourcesManager.isSameResourcesOverrideConfig(activityToken, amOverrideConfig)這個(gè)條件來設(shè)置shouldChangeConfig的值。如果shouldChangeConfig那么Activity的configuration在退出分屏后會(huì)更新為未分屏之前的值。

解決方案

為了解決這個(gè)問題,只需要將context更換為ApplicationContext即可。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,045評(píng)論 25 709
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 7,334評(píng)論 0 17
  • Android Studio JNI流程首先在java代碼聲明本地方法 用到native關(guān)鍵字 本地方法不用去實(shí)現(xiàn)...
    MigrationUK閱讀 12,089評(píng)論 7 123
  • 分手兩個(gè)多月了,說想念,太深沉。說不愛太違心,開始的倉促,到最后的后悔。一切一切的發(fā)展讓我以為不會(huì)一成不變,結(jié)果還...
    癡醒貓閱讀 299評(píng)論 0 0
  • 現(xiàn)在手機(jī)沒有網(wǎng),聊不到天。總結(jié)此刻的自己,沒有那么多的外在關(guān)注,形象變的潦潦草草,內(nèi)心輕松了很多,想干什么也不用準(zhǔn)...
    撿起遺失的夢閱讀 281評(píng)論 0 0

友情鏈接更多精彩內(nèi)容