Android Framework實戰視訊--FallbackHome結束啟動Launcher篇
課程答疑和新課資訊:QQ交流群:422901085進行課程討論
FrameWork入門課視訊連結:https://edu.csdn.net/course/detail/30298
FrameWork實戰課1視訊連結:https://edu.csdn.net/course/detail/30275
Android Framework實戰視訊–FallbackHome結束啟動Launcher篇
Android 8.1程式碼分析FallbackHome結束啟動Launcher篇:
1、FallbackHome的結束
上一講已經分析到了FallbackHome Activity的啟動,但其實FallbackHome只是系統由未解密到解密過程的一個過度介面,只要使用者把系統解鎖過一次後,那麼就一直會把系統的Home變成Launcher,這個時候FallbackHome的使命就已經完成,不會再出現了。所以經常使用者會發現現在手機普遍存在一個問題就是第一次解鎖手機會發現有1-2s的一個空白介面,接下來才是顯示Launcher的一個圖示介面。
那接下就詳細分析FallbackHome原始碼看看是怎麼結束的
這時候就需要去FallbackHome的Activity程式碼中看,原始碼路徑:packages/apps/Settings/src/com/android/settings/FallbackHome.java
//省略
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//省略
//註冊監聽系統的解鎖廣播
registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
maybeFinish();
}
@Override
protected void onResume() {
super.onResume();
if (mProvisioned) {
mHandler.postDelayed(mProgressTimeoutRunnable, PROGRESS_TIMEOUT);
}
}
@Override
protected void onPause() {
super.onPause();
mHandler.removeCallbacks(mProgressTimeoutRunnable);
}
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
//監聽系統的解鎖廣播,觸發檢測是不是該結束自己
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
maybeFinish();
}
};
//判斷是否該結束自己的方法
private void maybeFinish() {
if (getSystemService(UserManager.class).isUserUnlocked()) {
final Intent homeIntent = new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME);
final ResolveInfo homeInfo = getPackageManager().resolveActivity(homeIntent, 0);
//簡單判斷PMS中獲取到的Home型別的Activity還是不是自己,如果不是了,說明已解鎖,可以啟動真正Launcher了
if (Objects.equals(getPackageName(), homeInfo.activityInfo.packageName)) {
if (UserManager.isSplitSystemUser()
&& UserHandle.myUserId() == UserHandle.USER_SYSTEM) {
// This avoids the situation where the system user has no home activity after
// SUW and this activity continues to throw out warnings. See b/28870689.
return;
}
Log.d(TAG, "User unlocked but no home; let's hope someone enables one soon?");
mHandler.sendEmptyMessageDelayed(0, 500);
} else {
Log.d(TAG, "User unlocked and real home found; let's go!");
getSystemService(PowerManager.class).userActivity(
SystemClock.uptimeMillis(), false);
//這裡檢測到獲取的Home型別Activity已經不是自己,說明系統中真正Launcher已經可以獲取到了,則finish自己
finish();
}
}
}
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
maybeFinish();
}
};
}
註冊監聽系統的解鎖ACTION_USER_UNLOCKED廣播,根據這個條件來觸發檢測,本質上這裡其實FallbackHome就是一直在不斷的檢測系統中的獲取的Home 型別的Activtiy還是不是自己,如果不是了,比如師Launcher,那說明系統已經可以啟動真正Launcher了。
但細心同學會發現,這個只看到了FallbackHome finish自己,並沒有看到有啟動Launcher的操作?那Launcher到底是怎麼啟動的呢?
2、 Launcher的真正啟動
這裡如果正面分析可能會較為困難,即使我把對應的呼叫流程又重新給大家寫一遍對大家作用也不是很大,這裡給大家用我們的老方法打日誌堆疊的方式來輔助分析定位真正的Launcher是怎麼啟動的:
上節課已經分析了FallbackHome啟動是ActivityManagerService的startHomeActivityLocked,那麼有理由相信Launcher的啟動一樣會呼叫這個方法,所以在這個方法加入堆疊日誌列印,看到了系統啟動要進入Launcher時,有如下列印:
在
boolean startHomeActivityLocked(int userId, String reason) {
android.util.Log.i("test2","startHomeActivityLocked reason = " + reason,new Exception());
//省略。。。。
}
1521 1575 I test2 : startHomeActivityLocked reason = noMoreActivities resumeHomeStackTask
1521 1575 I test2 : java.lang.Exception
1521 1575 I test2 : at com.android.server.am.ActivityManagerService.startHomeActivityLocked(ActivityManagerService.java:4059)
1521 1575 I test2 : at com.android.server.am.ActivityStackSupervisor.resumeHomeStackTask(ActivityStackSupervisor.java:772)
1521 1575 I test2 : at com.android.server.am.ActivityStack.resumeTopActivityInNextFocusableStack(ActivityStack.java:2750)
1521 1575 I test2 : at com.android.server.am.ActivityStack.resumeTopActivityInnerLocked(ActivityStack.java:2313)
1521 1575 I test2 : at com.android.server.am.ActivityStack.resumeTopActivityUncheckedLocked(ActivityStack.java:2255)
1521 1575 I test2 : at com.android.server.am.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked(ActivityStackSupervisor.java:2103)
1521 1575 I test2 : at com.android.server.am.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked(ActivityStackSupervisor.java:2084)
1521 1575 I test2 : at com.android.server.am.ActivityStack.finishCurrentActivityLocked(ActivityStack.java:3901)
1521 1575 I test2 : at com.android.server.am.ActivityStack.completePauseLocked(ActivityStack.java:1445)
1521 1575 I test2 : at com.android.server.am.ActivityStack.activityPausedLocked(ActivityStack.java:1413)
1521 1575 I test2 : at com.android.server.am.ActivityManagerService.activityPaused(ActivityManagerService.java:7443)
1521 1575 I test2 : at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:317)
1521 1575 I test2 : at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2919)
1521 1575 I test2 : at android.os.Binder.execTransact(Binder.java:697)
明顯看到了這裡有呼叫startHomeActivityLocked,而且這次的reason是noMoreActivities resumeHomeStackTask,那麼到底是哪裡呼叫到這個地方呢?
這時候看堆疊就可以詳細準確定位出如下流程:
FallbackHome請求finish自己,當然會請求執行onPasue方法: ActivityManagerService.activityPaused --》觸發呼叫到ActivityStack.activityPausedLocked --》 呼叫到 ActivityStack.completePauseLocked —》 呼叫到 ActivityStack.finishCurrentActivityLocked --》呼叫到 ActivityStackSupervisor.resumeFocusedStackTopActivityLocked --》。。。。。。。-》最後呼叫到了ActivityManagerService.startHomeActivityLocked
如上堆疊一列印裡面把程式碼行數和方法都列印了,非常詳細,相比自己去一步步分析效率高出太多,也準確許多,不用去挨個每個條件進行分析。
到了startHomeActivityLocked之後相信有前幾節視訊帶領就不需要這裡再進行分析了。
好了那整個系列的實戰課程1就給大家分析完了,相信大家跟著視訊和部落格學習完成,自己去動手操作後一定會有不一樣的收穫,最後謝謝大家,後面如果想要關注課程資訊及作者答疑,請購買課程或者加入qq技術討論群(422901085)進行了解
最後祝大家android水平可以站在我的肩膀上飛起來飛得很高很高。。。。