activity的启动流程

现在让我们看下几个关系:Context (抽象类) -> ContextWrapper -> ContextThemeWrapper -> Activity 这就是集成关系表。

第一步:应用进程内工作 

当我们使用StartActivity(Intent intent)的时候,看看进入到activity的看下代码:

@Override
public void startActivity(Intent intent) {
    this.startActivity(intent, null);
}

调用了重载的startActivity()方法,我们看下,如下:

@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        startActivityForResult(intent, -1);
    }
}

进入到startActitivyForResult()方法中,我们看下:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        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());
        }
        if (requestCode >= 0) {
            mStartedActivity = true;
        }
        cancelInputsAndStartExitTransition(options);
    } 
}

这个方法中我们使用了mInstrumentation全局变量的execStartActivity()方法,那我们看看mInstrumentation是什么时候传进来的。进入到attach()方法中,我们看下,如下:

final void attach(Context context, ActivityThread aThread,
        Instrumentation instr, IBinder token, int ident,
        Application application, Intent intent, ActivityInfo info,
        CharSequence title, Activity parent, String id,
        NonConfigurationInstances lastNonConfigurationInstances,
        Configuration config, String referrer, IVoiceInteractor voiceInteractor,
        Window window, ActivityConfigCallback activityConfigCallback) {
    attachBaseContext(context);

    mFragments.attachHost(null /*parent*/);

    mWindow = new PhoneWindow(this, window, activityConfigCallback);
    mWindow.setWindowControllerCallback(this);
    mWindow.setCallback(this);
    mWindow.setOnWindowDismissedCallback(this);
    mWindow.getLayoutInflater().setPrivateFactory(this);
    if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
        mWindow.setSoftInputMode(info.softInputMode);
    }
    if (info.uiOptions != 0) {
        mWindow.setUiOptions(info.uiOptions);
    }
    mUiThread = Thread.currentThread();

    mMainThread = aThread;
    mInstrumentation = instr;

也就是说,在startActivityForResult()方法中,我们通过使用Instrumentation类进行向下走,我们现在进入到他的方法中看下:

 
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
      int result = ActivityManagerNative.getDefault()
            .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 RuntimeExceptio("Failure from system", e);
    }
    return null;
}

这样我们可以看到在方法中我们调用了ActivityManagerNative.getService()返回的类,然后使用了他的startActivity()方法,那让我们看看ActivityManger.getService()方法中返回的是什么对象?

static public IActivityManager getDefault() {
    return gDefault.get();  // Retrieve the system's default/global activity manager
}

返回了一个IActivityManager对象,这个IActivityManger和ActivityMangerProxy,ActivityMangerNative三个是什么关系呢?接着向下看把。现在让我们看看gDefault这个是什么东西?代码如下:

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
            protected IActivityManager create() {
                    IBinder b = ServiceManager.getService("activity");
                    if (false) {
                        Log.v("ActivityManager", "default service binder = " + b);
                    }
                    IActivityManager am = asInterface(b);
                    if (false) {
                        Log.v("ActivityManager", "default service = " + am);
                    }
                    return am;
                }
};

然后我们进入到ServiceManger类中看下getService()方法中看下,代码如下:

public static IBinder getService(String name) {
    try {
        IBinder service = sCache.get(name);
        if (service != null) {
            return service;
        } else {
            return getIServiceManager().getService(name);
        }
    } catch (RemoteException e) {
        Log.e(TAG, "error in getService", e);
    }
    return null;
}

然后我们发现他使用了getIServcieManger()方法,我们看看他做了些什么事情,如下:

private static IServiceManager getIServiceManager() {
     if (sServiceManager != null) {
             return sServiceManager;
         }

     // Find the service manager
     sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
     return sServiceManager;
 }

然后我们就再次返回到ServiceMangerNative中,查看asInterface()方法中。

static public IActivityManager asInterface(IBinder obj) {
     if (obj == null) {
          return null;
      }
     IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor);
     if (in != null) {
          return in;
      }
     return new ActivityManagerProxy(obj);
 }

这个方法我们返回了ActivityMangerProxy类。然后我们看下ActivtyMangerProxy这个类是继承了IActivityManger。

这个时候,我们先停下,看看IActivityManger和ActivityMangerProxy,ActivityMangerNative这个几个类的关系:

IActivityManger:是一个接口

ActivityMangerNative(抽象类):是IActivityManger的子类,同时继承了Binder。

ActivityMangerProxy:是IActivityManger的子类,同时他是ActivityMangerNative的内部类。

这样,我们也就明白了,真正实现跳转的是ActiivtyManagerProxy类中的startActivity()方法,然后我们看下代码:

public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
      String resolvedType, IBinder resultTo, String resultWho, int requestCode,
      int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
          Parcel data = Parcel.obtain();
          Parcel reply = Parcel.obtain();
          data.writeInterfaceToken(IActivityManager.descriptor);
          data.writeStrongBinder(caller != null ? caller.asBinder() : null);
          data.writeString(callingPackage);
          intent.writeToParcel(data, 0);
          data.writeString(resolvedType);
          data.writeStrongBinder(resultTo);
          data.writeString(resultWho);
          data.writeInt(requestCode);
          data.writeInt(startFlags);
          if (profilerInfo != null) {
                  data.writeInt(1);
                  profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
              } else {
                  data.writeInt(0);
              }
          if (options != null) {
                  data.writeInt(1);
                  options.writeToParcel(data, 0);
              } else {
                  data.writeInt(0);
              }
          mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
          reply.readException();
          int result = reply.readInt();
          reply.recycle();
          data.recycle();
          return result;
      }

这个方法,我们就将要传送的消息进行序列化。mRemote就是一个IBinder实例,我们进入其中的方法,可以看到:

public boolean transact(int code, Parcel data, Parcel reply, int flags)  throws RemoteException;

总结:

Activity - Instrumentation - ActivityManagerNative - ActivityManagerProxy 

第二步:理论讲解

上面我们已经知道ActivityManagerProxy继承与IActivityManager,到了这里就引出了我们android系统中很重要的一个概念:Binder机制。我们知道应用进程与SystemServer进程属于两个不同的进程,进程之间需要通讯,android系统采取了自身设计的Binder机制,这里的ActivityManagerProxy和ActivityManagerNative都是继承与IActivityManager,而SystemServer进程中的ActivityManagerService对象则继承与ActivityManagerNative。

这样,ActivityManagerNative与ActivityManagerProxy相当于一个Binder的客户端而ActivityManagerService相当于Binder的服务端,这样当ActivityManagerNative调用接口方法的时候底层通过Binder driver就会将请求数据与请求传递给server端,并在server端执行具体的接口逻辑。需要注意的是Binder机制是单向的,是异步的,也就是说只能通过client端向server端传递数据与请求而不同等待服务端的返回,也无法返回,那如果SystemServer进程想向应用进程传递数据怎么办?这时候就需要重新定义一个Binder请求以SystemServer为client端,以应用进程为server端,这样就是实现了两个进程之间的双向通讯。

ActivityManagerNative是ActivityManagerService在应用进程的一个client就好,通过ActivityManagerNative我们就可以调用(服务器)ActivityManagerService 中的方法了。

刚才我们执行到了ActivityManagerProxy类中的startActivity()方法,这个方法的目的就是通过数据传输之后就会调用SystemServer进程的ActivityManagerService的startActivity()。

第三步:SystemServer进程 工作流程

首先我们先打开ActivityMangerService这类中,首先我们看到的就是ActivityManagerService 是继承 ActivityManagerNative

然后我们看到startActivity()的代码如下:

@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
                               Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
                               int startFlags, ProfilerInfo profilerInfo, Bundle options) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, options,
            UserHandle.getCallingUserId());
}

这个方法调用类startActivityAsUser(),我们进入去看下,代码如下:

@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
                                     Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
                                     int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
     。。。//忽略一大堆的各种判断抛出异常的代码
    // TODO: Switch to user app stacks here.
    return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
            resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, null, null, options, false, userId, null, null);
}

这个方法很关键的地方是使用了mStackSupervisor这个实例的startActivityMayWait()方法。那现在让我们看看mStackSupervisor是个什么东西?是ActivityStarter 的实例,那ActivityStarter是什么呢,先不关心,继续代码如下:






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值