一.在桌面或抽屉显示应用图标
桌面或抽屉就是一个普通APP应用,用于显示所有应用图标
含有以下intent意图的Activity会显示在桌面或抽屉
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
二.点击桌面或抽屉的应用图标
Launcher.java{
...
public void onClick(View v)
...
// 新建任务栈Stack,用于存放目标应用的Activity
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent)
}
}
三.startActivity(...)过程
1.启功目标应用的任务栈Stack
2.通知源应用的主线程ActivityThread-调用Activity的onPause方法
3.调用Process_start创建新进程,加入目标应用主线程ActivityThread,执行main方法
ActivityThread.java{
// java程序入口
public static void main(String[] args) {
...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
// handle处理消息分发
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
4.在目标应用主线程中loadClass加载Activity类
Instrumentation.java{ // 监控应用与系统的交互
// 创建Activity实例对象
newActivity(...)
// 调用Activity生命周期的各种方法
callActivityOnCreate(...)
callActivityOnStart(...)
callActivityOnReStart(...)
callActivityOnResume(...)
callActivityOnPause(...)
callActivityOnStop(...)
callActivityOnDestroy(...)
callActivityOnSaveInstanceState(...)
callActivityOnRestoreInstanceState(...)
...
}
5.在Activity类setContentView加载布局
Activity.java{
attach(...) {
...
// 创建PhoneWindow extends Window类
mWindow = new PhoneWindow(this, window);
...
}
onCreate(...){
setContentView(...)
}
setContentView(...) {
getWindow().setContentView(...);
}
getWindow(){
return mWindow;
}
}
PhoneWindow.java{
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor();// 初始化父布局mContentParent
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
getContext());
transitionTo(newScene);
} else {
mLayoutInflater.inflate(layoutResID, mContentParent);
}
...
}
public void setContentView(View view) {
setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
public void setContentView(View view, ViewGroup.LayoutParams params) {
if (mContentParent == null) {
installDecor(); // 初始化父布局mContentParent
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
view.setLayoutParams(params);
final Scene newScene = new Scene(mContentParent, view);
transitionTo(newScene);
} else {
mContentParent.addView(view, params);
}
...
}
// 初始化父布局mContentParent
private void installDecor() {
mForceDecorInstall = false;
if (mDecor == null) {
mDecor = generateDecor(-1);
mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
mDecor.setIsRootNamespace(true);
if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
}
} else {
mDecor.setWindow(this);
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
...
}
}
protected ViewGroup generateLayout(DecorView decor) {
...
ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
...
return contentParent;
}
}
简书: http://www.jianshu.com/p/30f61733fdaf
CSDN博客: http://blog.csdn.net/qq_32115439/article/details/72905465
GitHub博客:http://lioil.win/2017/06/07/Android_Launcher.html
Coding博客:http://c.lioil.win/2017/06/07/Android_Launcher.html
网友评论