版本android28源码
继承关系总结:
Activity:ContextWrapper:Context
ContextImpl:Context(抽象类,实现在安卓框架)
ReceiverRestrictedContext:ContextWrapper
ActivityManagerNative(Deprecated,推荐直接使用ActivityManager方法了)
1 ActivityThread.main
ActivityThread是一个APP开始启动的地方,AMS通过反射调用ActivityThread的main函数,启动后准备好mainlooper,开始显式new ActivityThread();
ActivityThread内部的handler就开始运行,绑定到当前线程(主线程)
后面立马做了一个attach动作,做了一些和虚拟机有关的操作
(1).ViewRootImpl.addFirstDrawHandler{ensureJitEnabled()} 往ViewRootImpl的sFirstDrawHandlers的list里放入jvm初始化jit,在第一次draw的时候触发
(2).android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());//预设置进程名
(3).ActivityManager.attachApplication
(4).BinderInternal.addGcWatcher//用掉3/4的内存的时候,尝试释放一些activity
后续开启Looper.loop();永远在接收消息,主线程保持在阻塞状态,处理来自AMS的消息命令
ActivityClientRecord保存了一个activity的记录,包含生命周期等
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...}
新建流程
ActivityThread.java中有2个分支
handleRelaunchActivity->handleRelaunchActivityInner->handleLaunchActivity->performLaunchActivity
-startActivityNow()->performLaunchActivity()
startActivityNow新建了一个ActivityClientRecord对象包装了activity信息,来启动activity
performLaunchActivity中
1.mInstrumentation.newActivity //反射新建Activity 但是没有attach
2.Application app = r.packageInfo.makeApplication//新建并attach application 会调用app oncreate
3.activity.attach(进入app的activity内,新建PhoneWindow)
4.mInstrumentation.callActivityOnCreate(activity, r.state);//调用oncreate
5.在oncreate内固定调用setcontetview //安装decorview 添加layout
activity.attach的分析
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback)
第一行attachBaseContext(context); 最终ContextWrapper 将context存入内部mBase
activity提供的getMainLooper等大多数功能都是从context来
ContextThemeWrapper.java中一个有意思的地方,LAYOUT_INFLATER_SERVICE是单例模式生成在ContextThemeWrapper中的
ContextThemeWrapper.java
@Override
public Object getSystemService(String name) {//@1
if (LAYOUT_INFLATER_SERVICE.equals(name)) {
if (mInflater == null) {
mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);//@3
}
return mInflater;
}
return getBaseContext().getSystemService(name);
}
LayoutInflater.java
public static LayoutInflater from(Context context) {//@2
LayoutInflater LayoutInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (LayoutInflater == null) {
throw new AssertionError("LayoutInflater not found.");
}
return LayoutInflater;
}
LayoutInflater.from() 调用了2次,一般的入口是函数2,我主动调用的2
2内部调用1,1的内部也调用了LayoutInflater.from() 这个特殊调用称为3,3中的context是contextImp,所以getSystemService就不一样了
AndroidSDK\sources\android-28\android\app\SystemServiceRegistry.java
真正的LayoutInflater系统服务
registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,
new CachedServiceFetcher<LayoutInflater>() {
@Override
public LayoutInflater createService(ContextImpl ctx) {
return new PhoneLayoutInflater(ctx.getOuterContext());
}});
PhoneLayoutInflater.java
public LayoutInflater cloneInContext(Context newContext) {
return new PhoneLayoutInflater(this, newContext);
}
protected PhoneLayoutInflater(LayoutInflater original, Context newContext) {
super(original, newContext);
}
LayoutInflater.java
protected LayoutInflater(LayoutInflater original, Context newContext) {
mContext = newContext;
mFactory = original.mFactory;
mFactory2 = original.mFactory2;
mPrivateFactory = original.mPrivateFactory;
setFilter(original.mFilter);
}
PhoneLayoutInflater存在的意义
1.就是用外部context新建了一个inflater 避免把factory映射到系统inflater的factory里
2.重载onCreateView,兼容以.开头的安卓内部控件(.button-》android.widget.等前缀)
PhoneWindow的新建
Activity的attach内第三行
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
Activity的setContentView过程
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);//attach 创建的PhoneWindow
initWindowDecorActionBar();
}
window是代表窗口的抽象,只有唯一实现PhoneWindow
abstract class Window
public class PhoneWindow extends Window implements MenuBuilder.Callback
PhoneWindow 中的setContentView
// This is the top-level view of the window, containing the window decor.
private DecorView mDecor;
// This is the view in which the window contents are placed. It is either
// mDecor itself, or a child of mDecor where the contents go.
ViewGroup mContentParent;
@Override
public void setContentView(int layoutResID) {
// Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
// decor, when theme attributes and the like are crystalized. Do not check the feature
// before this happens.
if (mContentParent == null) {
installDecor();
} 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);
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
}
mContentParentExplicitlySet = true;
}
installDecor内
1.generateDecor 生成新DecorView到mDecor
2.mContentParent = generateLayout(mDecor);解析属性,生成layout
generateLayout中
1.R.layout.screen_custom_title里含有android.R.id.content
2.layoutResource = R.layout.screen_custom_title;
3.onResourcesLoaded(LayoutInflater inflater, int layoutResource)中DecorView添加layoutResource作为宽高都match_parent的子view
4.找到了ID_ANDROID_CONTENT 返回结果mContentParent
所以mContentParent 是我们添加布局的根节点
回到PhoneWindow 中的setContentView中
mLayoutInflater.inflate(layoutResID, mContentParent);终于将我们的布局加载到mContentParent下面了
activity
=外层PhoneWindow(Window的实现)
==DecorView(FrameLayout子类)
===mContentParent (ID_ANDROID_CONTENT,根布局)
oncreate只把layout安装上去,还没有开始显示layout
ActivityThread.java中
handleResumeActivity->performResumeActivity
handleNewIntent->performNewIntents->performResumeActivity
performResumeActivity中调用activity.performResume
1.performRestart(true /* start */, reason);//
2.mInstrumentation.callActivityOnResume(this);-》activity.onResume();
handleResumeActivity
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,String reason) {
...
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
...
final Activity a = r.activity;
...
View decor = r.window.getDecorView();
ViewManager wm = a.getWindowManager();
...
wm.addView(decor, l);//实际调用WindowManagerGlobal.addView,新建ViewRootImpl
PhoneWindow在新建后setWindowManager
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
WindowManager接口,实现在WindowManagerImpl
mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
每一个Window在setWindowManager的时候从系统服务中新建一个WindowManagerImpl
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
return new WindowManagerImpl(mContext, parentWindow);
}
重点就是parentWindow被设置为当前Window
所以activity中的getSystemService重载,对WINDOW_SERVICE返回mWindowManager(就是createLocalWindowManager新建的那个)
如果是在service里,getSystemService获得的是sysytem那个parentWindow为空的WindowManagerImpl。(补充:另外一个getSystemService重载的是SEARCH_SERVICE activity直接新建保存为内部变量了,没有用系统的,不知道为啥可能省略了一个入参handler的原因)
WindowManagerImpl的实际使用:代理模式代理\单例模式
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
WindowManagerGlobal单例管理所有的decorview,ViewRootImpl,wparams;缓存到3个对应的ArrayList,后续用同一个index取出。
WindowManagerGlobal.java
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
。。。
ViewRootImpl root;
root = new ViewRootImpl(view.getContext(), display);//新建ViewRootImpl
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
。。。
root.setView(view, wparams, panelParentView);
...
}
ViewRootImpl是在addview里创建的。
ViewRootImpl.setView-》requestLayout()-》scheduleTraversals
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
doTraversal-》performTraversals-》(dispatchAttachedToWindow/performMeasure/performLayout/performDraw)
performTraversals第一次运行 会把DecorView Attache到window,由于decorView是viewgroup,会递归调用子view的dispatchAttachedToWindow
他们都使用viewgroupiml新建的View.AttachInfo
final View host = mView;
if (mFirst) {
host.dispatchAttachedToWindow(mAttachInfo, 0);
mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true);
dispatchApplyInsets(host);
}
===============================================
private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
if (mView == null) {
return;
}
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
try {
mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
int desiredWindowHeight) {
mLayoutRequested = false;
mScrollMayChange = true;
mInLayout = true;
final View host = mView;
if (host == null) {
return;
}
if (DEBUG_ORIENTATION || DEBUG_LAYOUT) {
Log.v(mTag, "Laying out " + host + " to (" +
host.getMeasuredWidth() + ", " + host.getMeasuredHeight() + ")");
}
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "layout");
try {
host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
...
}
performDraw-》draw-》drawSoftware->mView.draw(canvas);
进入到view的draw过程