android那两个你碰不到但是很重要的类之activitythread-kb88凯时官网登录

来自:网络
时间:2023-07-25
阅读:
目录

前言

上篇文章我们聊了些android里那些我们平时碰不到但很重要的类viewrootimpl,这一篇我们就来看看另外那个类activitythread。

通过本文能了解一下内容

android那两个你碰不到但是很重要的类之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传递过去。mappthreadapplicationthread的一个对象,是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。

android那两个你碰不到但是很重要的类之activitythread

  • 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.javahandleresumeactivity()有这样一段代码,我们可以得出结论,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的资料请关注其它相关文章!

返回顶部
顶部
网站地图