美文网首页
ActivityThread

ActivityThread

作者: waiwaaa | 来源:发表于2020-05-13 20:25 被阅读0次

ActivityThread

1 几个重要的成员变量

(1)ApplicationThread

final ApplicationThread mAppThread = new ApplicationThread();

ApplicationThread是ActivityThread的内部类,ActivityThread与启动Activity有关,那么ApplicationThread就与启动Application有关了。

(2)H

final H mH = new H();

H继承与Handle,重写了handleMessage的方法,这个类主要作用就是根据不同的情况处理各种业务,而且处理业务的方法一般是以handle开头,handleXXX的格式,如下:

handleActivityConfigurationChanged()
handleBindApplication()
handleBindService()
handleCancelVisibleBehind()
handleConfigurationChanged()
handleCreateService()
handleDestroyActivity()
handleDispatchPackageBroadcast()
handleLaunchActivity()//启动一个Activity
handleLowMemory()
handleMessage()
handleNewIntent()
handlePauseActivity()
handleReceiver()
handleRelaunchActivity()
handleResumeActivity()
handleSendResult()
handleServiceArgs()
handleStopActivity()
handleStopService()

这些函数有的又会调用到如下的performXXX系列函数完成最终的事件处理:

performDestroyActivity()
performDestroyActivity()
performLaunchActivity()//创建Activity实例
performNewIntents()
performPauseActivity()
performPauseActivity()
performRestartActivity()
performResumeActivity()
performStopActivity()
performStopActivityInner()
performUserLeavingActivity()

(3)mActivities

final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
mActivities包含了当前进程的所有的activity,注意不是简单的把activity做了数据集合,而是封装成了ActivityClientRecord,ActivityClientRecord不仅仅保存了Activity本身及其相关的信息,还会保存与该Activity有关的成员(例如window、windowManager等)。往mActivities里添加内容的源码

//ActivityThread#performLaunchActivity:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
       ......
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            // 1.创建一个Activity实例,mInstrumentation为Instrumentation类型,
           //用来监控系统组件与应用的交互过程,里面有很多方法供回调
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            ......
        } catch (Exception e) {
          ......
        }

        try {
            // 2.获取一个Application实例
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            ......
            if (activity != null) {
                // 3. 创建一个上下文实例
                Context appContext = createBaseContextForActivity(r, activity);
                //获取标题
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
               ......
                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    //如果r.mPendingRemoveWindow 不为null,就是直接拿来使用
                    window = r.mPendingRemoveWindow;
                    //重置r.mPendingRemoveWindow,r.mPendingRemoveWindowManager为null
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }
                // 4.在这个方法中将会绑定上下文,创建一个窗口实例,获取窗口管理器等
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window);

                ......
                activity.mStartedActivity = false;
                //activity主题资源id
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                if (r.isPersistable()) {//调用Activity的OnCreate方法
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                 ......
                //保存刚刚创建的Activity实例到r.activity中
                r.activity = activity;
                r.stopped = true;
                if (!r.activity.mFinished) {
                    //在这个方法中最终会调用Activity的onStart函数,当然是通过Instrumentation调用的
                    activity.performStart();
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {
                    if (r.isPersistable()) {
                        if (r.state != null || r.persistentState != null) {
                           //通过Instrumentation调用Activity的performRestoreInstanceState函数
                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                    r.persistentState);
                        }
                    } else if (r.state != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    if (r.isPersistable()) {
                  //通过Instrumentation调用Activity的onPostCreate函数
                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
                                r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    }
                    ......
                }
            }
            r.paused = true;
            // 5.关键的来了,在这里把ActivityClientRecord的对象引用放置到mActivities中
            mActivities.put(r.token, r);

        } catch (SuperNotCalledException e) {
         ......
        } catch (Exception e) {
           ......
        }
        //返回刚刚创建的Activity实例
        return activity;
    }

//说明,注意红色的部分,把封装好的ActivityClientRecord保存到mActivities中,而这个方法的主要作用就是(1)创建一个Activity实例(2)获取一个Application实例(3)创建一个Context实例(4)保存该Activity相关信息到mActivities(5)调用attach实现Activity、Context之间的绑定及窗口、WMS的创建。

(4)mServices

final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
与mActivities相似,mServices就是储存当前进程所用的Service实例。

(5)其他成员变量

//很明显这个集合就是为了保存Application实例的,一个APP应用中使用一个类继承Application,子类的onCreate只被调用一次,
//这里为什么使用集合了呢
//在LoadedAPK的makeApplication方法也能体现这一点,mApplication为null就创建一个Application实例,否则就返回它。
//但是其下面还有一行代码:mActivityThread.mAllApplications.add(app);在这里把刚刚创建Application实例到
//mAllApplications中保存起来了,那只有LoadedAPK角度分析,会发现在handleReceiver、handleCreateService方法
//都有创建LoadedAPK实例,也调用了 makeApplication方法当然这个时候也会创建一个Application实例,
//所以不要单纯地以为只有启动Activity的时候才使用Application。
final ArrayList<Application> mAllApplications = new ArrayList<Application>();
//这个集合是为了保存LoadedApk实例,进一步证明了Application实例可不只会被创建一个
final ArrayMap<String, WeakReference<LoadedApk>> mPackages = new ArrayMap<String, WeakReference<LoadedApk>>();
//下面这两个集合都为Provider,只是方式不一样
final ArrayMap<ProviderKey,ProviderClientRecord> mProviderMap = new ArrayMap<ProviderKey,ProviderClientRecord>();
final ArrayMap<IBinder,ProviderClientRecord> mLocalProviders = new ArrayMap<IBinder ProviderClientRecord>();

2 内部类

static final class BindServiceData //用来封装使用bindeservice启动的时候的service的信息.
static final class ReceiverData   //用来封装和广播处理相关的一些信息.
final class ProviderClientRecord  //用来封装和Provider交互的一些信息
static final class AppBindData    //用来封装和Application交互时的一些信息

3 main函数分析

ActivityThread的入口函数如下:

public static void main(String[] args) {
        ......
        //启动性能统计器
        SamplingProfilerIntegration.start();
        //关闭CloseGuard
        CloseGuard.setEnabled(false);
        //初始化用户环境
        Environment.initForCurrentUser();
        ......
        // 获取用户配置文件目录
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        //设置配置文件存储默认目录
        TrustedCertificateStore.setDefaultUserDirectory(configDir);
        //Change this process's argv[0] parameter.  This can be useful to show
       //more descriptive information in things like the 'ps' command.
        Process.setArgV0("<pre-initialized>");
        //初始当前线程为Looper线程
        Looper.prepareMainLooper();
       //创建一个ActivityThread实例
        ActivityThread thread = new ActivityThread();
        //绑定应用,attach是一个非常重要的函数 这个过程下文详细介绍
        thread.attach(false);
        //获取Handle实例,其实获取的是Handle子类H对象引用,在H中添加了处理各种消息的业务
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        ......
        //开始循环
        Looper.loop();
        //异常退出,将抛出异常
        throw new RuntimeException("Main thread loop unexpectedly exited");
}

4 ApplicationThread

1.作用

ApplicationThread是ActivityThread的内部类,也是一个Binder对象。在此处它是作为IApplicationThread对象的server端等待client端的请求然后进行处理,最大的client就是AMS.
继承了ApplicationThreadNative的,并且它内部有非常多的scheduleXXX的方法.以后看到thread调用这个方法 就可以往这边找。我们先说一下这些方法,这些方法由外部的ActivityThread的binder远程代理对象调用最终走到这里.这些 schedulexxx的方法会进一步的通过往外发送消息给mH这个消息队列.来做处理.

2. ApplicationThreadNative

ApplicationThread承继ApplicationThreadNative,它完成了作为服务端的构架。
该类实现业务接口IApplicationThread,非常标准的Binder模板.IApplicationThread
extends IInterface它里面就是定义了非常多的通信的业务接口,也都是schedulexxx理解上对应到ApplicationThread那些方法。
该类首先是提供了一个静态的方法asInterface()用来获取IApplicationThread的Binder对象或者Binder代理对象,其它进程跨进程调用时候当传入的是BinderProxy那么就会返回一个ApplicationThreadProxy对象并把BinderProxy传入它的构造,而一般在本进程中调用的时候,就直接返回当前IApplicationThread对象,然后就是onTransact()函数了,里面通过不同的code对应到不同的case,进而调用不同的schedulexxx的方法,最终调用ApplicationThread中的schedulexxx方法

3. ApplicationThreadProxy

代理端的标准实现,实现了IApplicationThread 接口,然后实现接口中定义的业务方法,在每个方法中最终调用到了服务端的对应的schedulexxx方法中。
AMS用的时候通过ActivityThread的接口获得到ApplicationThread的对象,然后传入到asInterface(),获取对应的IApplicationThread对象进行跨进程调用。

4. Instrumentation

在android.app包下有Instrumentation这个类,这个类没有继承和实现其它的任何类,也没被其它的类继承。它会在应用的任何代码执行前被实例化,用来监控系统组件与应用的交互过程,还可以在配置文件中使用Instrumentation对Android组件单元测试。
每一个应用进程中只有唯一的Instrumentation, 在ActivityThread中成员变量Instrumentation mInstrumentation,通过方法 public Instrumentation
getInstrumentation()来获得该对象实例。
了解更多点击查看《Instrumentation

总结

image.png

整个ActivityThread框架是基于Binder通信的C/S结构,从图可知Server端是ActivityThread、ApplicationThread,Client是AMS(ActivityManagerService),而ApplicationThreadProxy可以看作AMS中Server代表。

代码基于Android24

相关文章

网友评论

      本文标题:ActivityThread

      本文链接:https://www.haomeiwen.com/subject/rwqinhtx.html