目录
- 前言
- 1、和系统进程打交道的桥头堡
- 2、为什么使用contentprovider可以实现初始化
- 3、activity是什么时候开始渲染的
- 4、原来还可以监控组件的生命周期
- 5 、sharedpreference被声讨的根源
- 7 、总结
前言
上篇文章我们聊了些android
里那些我们平时碰不到但很重要的类viewrootimpl
,这一篇我们就来看看另外那个类activitythread。
通过本文能了解一下内容
1、和系统进程打交道的桥头堡
应用进程起来之后art(android runtime)第一站就是activitythread,代码层面上就是activitythread的main()方法,是不是很熟悉,爷青回啊,这不就是java的main方法嘛
public static void main(string[] args) { looper.preparemainlooper(); activitythread thread = new activitythread(); thread.attach(false, startseq); smainthreadhandler = thread.gethandler(); looper.loop(); throw new runtimeexception("main thread loop unexpectedly exited"); }
该方法是一个静态方法,里面做了重要的两件事
- 创建了让主线程looper开始工作,并创建了一个handler
- 给system_server【递纸条】告诉他d88尊龙官网手机app的联系方式,告诉sytem_servr进程与应用进程取得联系可以通过applicationthread这个binder。看下面这个代码
private void attach(boolean system, long startseq) { final iactivitymanager mgr = activitymanager.getservice(); mgr.attachapplication(mappthread, startseq);//调用远端的binder }
- 通过
activitymanager.getservice()
拿到system_server
进程的binder,然后把mappthread
binder传递过去。mappthread
是applicationthread
的一个对象,是activitythread的一个内部类。 - 取得联系后的第一站创建applicaiton。
private class applicationthread extends iapplicationthread.stub { @override public final void bindapplication() { sendmessage(h.bind_application, data); }
- 接下来就是h主线程的hanlder,调用handlebindapplication
private void handlebindapplication(appbinddata data) { application app; data.info = getpackageinfonocheck(data.appinfo, data.compatinfo, issdksandbox);//内部创建loadedapk app = data.info.makeapplicationinner(data.restrictedbackupmode, null);//内部创建applicaiton对象,调用oncreate()方法 installcontentproviders(app, data.providers); //cotentprovider初始化 minstrumentation.callapplicationoncreate(app);//调用oncreate()方法 }
- 这里找到了为什么使用contentprovider能够实现初始化,构建的时候会创建contenprovider。
- iactivitymanager(binder):应用进程和systemserver进程打交道的时候。
- appliactionthread(binder):systemserver进程与应用进程通信。
2、为什么使用contentprovider可以实现初始化
private void handlebindapplication(appbinddata data) { application app; data.info = getpackageinfonocheck(data.appinfo, data.compatinfo, issdksandbox);//内部创建loadedapk app = data.info.makeapplicationinner(data.restrictedbackupmode, null);//内部创建applicaiton对象,调用oncreate()方法 installcontentproviders(app, data.providers); //cotentprovider初始化 minstrumentation.callapplicationoncreate(app);//调用oncreate()方法 }
上一段分析时已经找打了答案,应用进程被拉起来之后,在创建application
对象调用attachbasecontext()和oncreate()方法之间会调用contentprovider的oncreate()方法这也是很多第三方sdk使用该特性实现初始化的原理。
3、activity是什么时候开始渲染的
public void handleresumeactivity() { performresumeactivity(r, finalstaterequest, reason)//调用activity onresume final activity a = r.activity; view decor = r.window.getdecorview(); viewmanager wm = a.getwindowmanager(); a.mwindowadded = true; wm.addview(decor, l); }
activitythread.java的
handleresumeactivity()有这样一段代码,我们可以得出结论,activity渲染的起点是在
onresume
阶段,在onresume阶段会把decorview交给windowmanager开始执行渲染。
4、原来还可以监控组件的生命周期
class h extends handler { public static final int receiver = 113; //广播接收者 @unsupportedappusage public static final int create_service = 114;//service创建 public static final int install_provider = 145;//contentprovider public static final int relaunch_activity = 160; //activity启动 public void handlemessage(message msg) { if (debug_messages) slog.v(tag, ">>> handling: " codetostring(msg.what)); switch (msg.what) { case bind_application: trace.tracebegin(trace.trace_tag_activity_manager, "bindapplication"); appbinddata data = (appbinddata)msg.obj; handlebindapplication(data); trace.traceend(trace.trace_tag_activity_manager); break; case receiver: handlereceiver((receiverdata)msg.obj); break; case create_service: handlecreateservice((createservicedata)msg.obj); break; case bind_service: handlebindservice((bindservicedata)msg.obj); break; case relaunch_activity: handlerelaunchactivitylocally((ibinder) msg.obj); break; } } }
系统进程(system_server)指挥应用进程组件生命周期的第一站其实就在activitythread这里,交给h对象其实是主线程的handler来分发处理,如上。我们可以反射拿到这一信息,可以监控到主线程对于这些组件调度的信息,这一信息对我们监控排查anr很有帮助。
5 、sharedpreference被声讨的根源
private void handlestopservice(ibinder token) { queuedwork.waittofinish(); } public void handlepauseactivity(){ queuedwork.waittofinish(); } public void handlestopactivity(){ queuedwork.waittofinish(); } public void handleserviceargs(){ queuedwork.waittofinish(); }
activitythread的以上方法里会调用 queuedwork.waittofinish();
该代码会堵塞主线程执行等待sp的写入操作。这也是sp造成anr的根源。
稍微展开点
public static void waittofinish() { while (true) { runnable finisher; synchronized (slock) { finisher = sfinishers.poll(); } if (finisher == null) { break; } finisher.run(); } } }
waittofinish()
方法里有这样一段代码,sfinishers是一个list里面是存放的sp写入操作,会在sp执行commit
和apply的时候放入进来。字节跳动团队就是在此处hook了使其poll()
方法永远放回空,来杜绝此处产生的anr。
7 、总结
通过阅读activitythread的源码我们能在其中获取很多有用的知识。系统进程和应用进程通信的桥梁,activity真正渲染的起始点,contentprovider
能实现sdk自动初始化的原理等都在activitythread
看到他们的影子,希望本文对你有所启发有所帮助。
以上就是android那两个你碰不到但是很重要的类之activitythread的详细内容,更多关于android activitythread的资料请关注其它相关文章!