Android那两个你碰不到可是很重要的类之ActivityThread

前语

上篇文章咱们聊了些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【递纸条】告知他联系方式,告知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。
 public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        String pkg = intent != null && intent.getComponent() != null
                ? intent.getComponent().getPackageName() : null;
        return getFactory(pkg).instantiateActivity(cl, className, intent);//加载创立Activity
    }

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看到他们的影子,期望本文对你有所启示有所协助。