Android8.0中Activity启动流程分析(一)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wanggang514260663/article/details/87024964

Activity的启动流程比较繁琐,所以会分为几篇文章去做说明

1、Activity#startActivity

public void startActivity(Intent intent, @Nullable Bundle options) {
   if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        // Note we want to go through this call for compatibility with
        // applications that may have overridden the method.
        startActivityForResult(intent, -1);
    }
}

很常用,可以看到调用了startActivityForResult,默认设置了requestCode为-1。

2、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);
         if (ar != null) {
             mMainThread.sendActivityResult(
                 mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                 ar.getResultData());
         }
       ...
     } else {
       ...   //api13之后已经废除,所以不关注
     }
 }

mParent指代的是ActivityGroup,在api13之前,实现底部tab切换,是可以多个activity切换,之后被弃用了,使用Fragment代替,所以只看mParent == null分支。

execStartActivity传入的参数中,有一个mMainThread.getApplicationThread(),而当我们点开execStartActivity方法会发现,这个是一个IBinder对象

 ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options)

mMainThread.getApplicationThread()方法返回的是一个ApplicationThread对象,而ApplicationThreadActivityThread的一个内部类,暂时对于这个类不做说明,后面会用到,先看主要流程。

接下来看mInstrumentation.execStartActivity

3、Instrumentation#execStartActivity

 public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
   IApplicationThread whoThread = (IApplicationThread) contextThread;
   ...  //省略部分代码
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        int result = ActivityManager.getService()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

这里重点关心如下代码

int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);

ActivityManager.getService()方法操作如下

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;
            }
        };

Singleton实现如下

public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

Singletonget()方法实际上是返回了构造的对象,而且是单例形态。所以只会构造一次。而且用户构造对象的create()方法是一个抽象方法。所以实际构造是用的是如下代码

final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
 return am;

ServiceManager是用来管理系统服务的,可以看到这里是拿到activity的服务。这两行代码其实就是使用Binder机制进行通信,而IActivityManager的实现实际上就是ActivityManagerService。再结合ActivityManager.getService() .startActivity可以知道实际上是调用了ActivityManagerServicestartActivity方法。

接下来就是分析启动过程在ActivityManagerService中的操作了,下一篇见。

猜你喜欢

转载自blog.csdn.net/wanggang514260663/article/details/87024964