Android进阶知识树——Android四大组件启动过程

Android的四大钻无论对开发者或是用户都意义重大,对于用户来说应用就是Activity,用户所能看到的和交互的都发生在Activity中,对于开发者来说四大组件更是开发功能个展示功能的基础和媒介,对于初级开发者每天的工作都在和四大组件打交道,它也成为初级开发者成长的重要一关,本文就从过年源码的角度分析下四大组件的启动过程;

1、Activity启动过程

Activity是我们打交道最多的组件,也是初学者接触最早的组件,特的使用范围和频率也最多,使用如此频繁的Activity你究竟了解多少呢?下面从源码的角度一起分析一下Activity的启动过程,在分析源码之前先介绍两个系统服务接口IActivityManager和IApplicationThread,它们都是在服务端只用Binder通信,(关于BinderAndroid进阶知识树——Android 多进程、Binder 你必须知道的一切)具体在本地的两个代理类如下:

  • IApplicationThread
class ApplicationThread extends IApplicationThread.Stub{
   ...}
  • IActivityManager
class ActivityManagerService extends IActivityManager.Stub{
   ……}

由上面的两个代理类知道,系统中使用AIDL实现客户端和服务端的通信,介绍这两个代理类后,这里先介绍下程序在IActivityManager中如何与IApplicationThread交互的,开发者都知道Android程序的开始会执行ActivityThread.main()方法,在main()中创建了ApplicationThread实例并完成了在Ams中的设置

final ApplicationThread mAppThread = new ApplicationThread(); // 实例化ApplicaitonThread

ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);//main()中调用attach()

 private void attach(boolean system, long startSeq) {
   
     final IActivityManager mgr = ActivityManager.getService(); 
     mgr.attachApplication(mAppThread, startSeq);
 }

在main()方法中调用了attach(),attach()中通过ActivityManager.getService()获取IActivityManager接口的代理类AMS,然后调用AMS.attachApplication()传入mAppThread对象;

  @Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {
   
        synchronized (this) {
   
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        }
    }

在attachApplication中调用attachApplicationLocked()传入thread对象,attachApplicationLocked中调用了ProcessRecord.makeActive()在内部保存thread,这样AMS中就持有了ApplicationThread中代理的Binder对象;

  app.makeActive(thread, mProcessStats); //
  
    public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
   
            thread = _thread;
    }

上面实现了AMS和ApplicationThread的通信,那下面开始进入Activity的启动过程分析;

  • 执行启动Activity
startActivity()

Activity的启动是从一句startActivity()开始的,无论是否使用RequestCode启动,启动过程最终都会调用Activity的startActivityForResult()

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
   
        if (mParent == null) {
   
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
          }
  }

startActivityForResult()中调用会调用Instrumentation.execStartActivity(),Instrumentation在程序的启动和Activity的启动中起着重要的作用,而且在插件化中通过Hook系统中的Instrumentation对象还可以实现更多的功能,本篇指分析和Activity启动相关的

  • execStartActivity()
int result = ActivityManager.getService() //1
    .startActivity(whoThread, who.getBasePackageName(), intent,
            intent.resolveTypeIfNeeded(who.getContentResolver()),
            token, target != null ? target.mEmbeddedID : null,
            requestCode, 0, null, options);
checkStartActivityResult(result, intent);  //2、检查Activity的启动结果
  1. 注释1处调用IActivityManager代理类,IActivityManager是系统的服务接口,在此处采用Binder通信,ActivityManager.getService() 获取到的是它代理实现类ActivityManagerService,然后调用ActivityManagerService.startActivity()方法启动活动
  2. 在AMS启动活动后,调用checkStartActivityResult()检查启动结果,会根据具体的失败原因抛出异常
  • ActivityManager.getService():获取IActivityManager的代理类
public static IActivityManager getService() {
   
    return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
   
            @Override
            protected IActivityManager create() {
   
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                return am;
            }
        };

此处参照Android 8.1 源码,在系统中IActivityManager使用Singleton封装单例提供,在getService()中通过IActivityManagerSingleton.get()获取,get()会调用Singleton的create()通过ServiceManager获取对应的Binder,在根据Binder获取代理对象即ActivityManagerService对象,到此程序进入AMS中

  • AMS中的startActivity()中经过一系列的调用代码最终执行到ActivityStackSupervisor的realStartActivityLocked(),realStartActivityLocked中调用IApplication接口方法处理LaunchActivity
  app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                        System.identityHashCode(r), r.info,
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, !andResume,
                        mService.isNextTransitionForward(), profilerInfo);

此处IApplication接口的代理类为ApplicationThread,也就是方法最终进入ApplicationThread类中,ApplicationThread为ActivityThread中的内部类,它通过Handler发送消息方式与ActivityThread通信;

 @Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
   
            ActivityClientRecord r = new ActivityClientRecord();
          .......
            r.overrideConfig = overrideConfig;
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

ApplicationThread中创建ActivityClientRecord对象保存活动信息,然后发送Handler消息,handler消息最终被ActivityThread中的Handler子类H所消耗,在H的handleMessage()中最终调用ActivityThread中startActivityNow()方法;

  • ActivityThread的startActivityNow()来启动Activity
public final Activity startActivityNow(){
   
ActivityClientRecord record = new ActivityClientRecord()// 1
r.token = token;
r.ident = 0;
r.intent = intent;
r.state = state;
r.parent = parent;
r.embeddedID = id;
r.activityInfo = activityInfo;
r.lastNonConfigurationInstances = lastNonConfigurationInstances;
return performLaunchActivity(r, null);//2
}

在startActivityNow()中,首先创建ActivityClientRecord保存activity启动信息,然后直接调用performLaunchActivity()启动活动,performLaunchActivity方法至关重要,Activity的一系列的初始化都在其中完成;

1.1、performLaunchActivity()
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
   
ContextImpl appContext = createBaseContextForActivity(r);   //1、
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); //2、调用Instrumentation实例的方法
 ContextImpl appContext = createBaseContextForActivity(r); //3、创建Activity的Context对象
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, r.configCallback);
//5
if (r.isPersistable()) {
   
    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
   
    mInstrumentation.callActivityOnCreate(activity, r.state);
}
r.setState(ON_CREATE)
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值