Android 5.0原生bug及修複方法,android5.0bug
Android 5.0已經來了,這個版本改動非常大,也意味著會有更多的bug隱藏在其中,我會在這篇文章中一直更新自己遇到的原生bug及修複方法。
1、bug1
現象:
5.0中ActivityManagerService.keyguardWaitingForActivityDrawn ()介面替換了4.4中ActivityManagerService.dismissKeyguardOnNextActivity()介面,但是帶來了一個顯示bug,現象是keyguard隱藏後activity視窗還沒顯示出來,先看到的是launcher介面,接著才會顯示目標activity視窗。
原因分析:
5.0上觸發調用ActivityStackSupervisor.notifyActivityDrawnForKeyguard()時機提前置致。
解決方案:
注釋掉ActivityStack.completeResumeLocked()函數中對notifyActivityDrawnForKeyguard()函數的調用。
frameworks\base\services\java\com\android\server\am\ActivityStack.java
private void completeResumeLocked(ActivityRecord next) { next.idle = false; next.results = null; next.newIntents = null; if (next.isHomeActivity() && next.isNotResolverActivity()) { ProcessRecord app = next.task.mActivities.get(0).app; if (app != null && app != mService.mHomeProcess) { mService.mHomeProcess = app; } } if (next.nowVisible) { // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now. //mStackSupervisor.notifyActivityDrawnForKeyguard(); //注釋掉 }
2、bug2
現象:
一個父視窗擁有兩個子視窗,且子視窗的type類型一致,兩個子視窗有前後添加順序,當兩個子視窗同時顯示時然後按下home鍵進入後台,再從案頭啟動這個應用,會發現兩個子視窗相對上下位置發生對調。
原因分析:
有兩個原因,一是子視窗type類型不該一致,二是WindowManagerService針對兩個子視窗type類型一致時邏輯不健全。
解決辦法:
方法一:將兩個子視窗type類型變更;
方法二:在WindowState的建構函式修改子視窗添加邏輯;
frameworks\base\services\java\com\android\server\am\WindowState.java
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a, int viewVisibility, final DisplayContent displayContent) { .............. if (children_size == 0) { mAttachedWindow.mChildWindows.add(this); } else { for (int i = 0; i < children_size; i++) { WindowState child = (WindowState)mAttachedWindow.mChildWindows.get(i); if (this.mSubLayer < child.mSubLayer) { mAttachedWindow.mChildWindows.add(i, this); break; } else if (this.mSubLayer > child.mSubLayer) { continue; } if (this.mBaseLayer <= child.mBaseLayer) { mAttachedWindow.mChildWindows.add(i, this); break; } else { continue; } } if (children_size == mAttachedWindow.mChildWindows.size()) { mAttachedWindow.mChildWindows.add(this); } } ..........}
3、bug3
現象:
兩個activity之間跳轉時都加上Intent.FLAG_ACTIVITY_REORDER_TO_FRONT這個flag,按照A-->B-->A跳轉後,按下back鍵,此時必會引起launcher ANR。
原因分析:
加上Intent.FLAG_ACTIVITY_REORDER_TO_FRONT進行A-->B-->A跳轉後,由於focused activity沒有更新為A,導致WMS中尋找focused window為null,key事件上報找不到focused window以致無法分發key事件,最終導致launcher ANR。
解決辦法:
在ActivityStackSupervisor.startActivityUncheckedLocked()函數中加上mService.setFocusedActivityLocked(targetStack.topRunningActivityLocked(null));語句。
frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java
final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord, int startFlags, boolean doResume, Bundle options) {.............else if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { // In this case, we are launching an activity in our own task // that may already be running somewhere in the history, and // we want to shuffle it to the front of the stack if so. final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); if (top != null) { final TaskRecord task = top.task; task.moveActivityToFrontLocked(top); ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); top.updateOptionsLocked(options); top.deliverNewIntentLocked(callingUid, r.intent); targetStack.mLastPausedActivity = null; if (doResume) { targetStack.resumeTopActivityLocked(null); mService.setFocusedActivityLocked(targetStack.topRunningActivityLocked(null)); //添加該語句; } return ActivityManager.START_DELIVERED_TO_TOP; } }..........}
待續。