Activity的工作过程


一、Activity的启动过程?

Acivity的工作过程,在显示调用的情形下,只需要通过如下代码即可完成:
Intent intent=new Intent(this,TestActivity.class);
startActivity(intent);

startActivity方法存在多种重载方式,但最终都会调用到startActivityForResult方法,其具体实现如下所示。

public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
    
    
    //一般的Activity的mParent为null
    if (mParent == null) {
    
    
        //调用Instrumentation.execStartActivity()启动新的Activity。mMainThread类型为ActivityThread, 在attach()函数被回调时被赋值。 
        Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
        if (ar != null) {
    
        // 如果activity之前已经启动,而且处于阻塞状态,execStartActivity函数直接返回要启动的activity的result或者null。(注意:这就是Activity.onActivityResult()会在启动另外一个activity启动时被回调的原因。
            // 若result非空,发送结果给本activity,即onActivityResult会被调用。
            mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                                            ar.getResultData());
        }
        if (requestCode >= 0) {
    
    
            // 如果这次启动需要被启动的activity返回一个结果,则在收到返回结果前,本activity保持不可见。
            mStartedActivity = true;
        }
 
        final View decor = mWindow != null ? mWindow.peekDecorView() : null;
        if (decor != null) {
    
    
            decor.cancelPendingInputEvents();
        }
        // TODO Consider clearing/flushing other event sources and events for child windows.
    } else {
    
    
        //在ActivityGroup内部的Activity调用startActivity的时候会走到这里,内部处理逻辑和上面是类似的
        if (options != null) {
    
    
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {
    
    
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}

方法里面主要关注 Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options)执行语句,查看execStartActivity方法内部执行逻辑。
根据方法参数的类型可知mMainThread.getApplicationThread()返回ActivityThread对象即IBinder对象

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    
    
    //将contextThread转成ApplicationThread.
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    if (mActivityMonitors != null) {
    
    
        synchronized (mSync) {
    
    
             //检查是否存在这个activity
            final int N = mActivityMonitors.size();
            for (int i=0; i<N; i++) {
    
    
                 final ActivityMonitor am = mActivityMonitors.get(i);
                 if (am.match(who, null, intent)) {
    
    
                     am.mHits++;
                     if (am.isBlocking()) {
    
                           //若找到,而且处于阻塞状态,直接返回。
                         return requestCode >= 0 ? am.getResult() : null;
                     }
                     break;
                }
            }
        }
    }
    try {
    
    
        intent.migrateExtraStreamToClipData();     //转移数据
        intent.prepareToLeaveProcess();            //准备让intent离开一个app进程
        //通过AcitivityManagerNative与ActivityManagerService关联起来,两个类的关系如下图,由ActivityManagerService去执行实际动作。
        int result = ActivityManagerNative.getDefault()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, null, options);
        //检查启动结果,如果无法打开activity,则抛出诸如ActivityNotFoundException类似的各种异常
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
    
    
    }
    return null;
}

函数里面主要通过 ActivityManagerNative.getDefault().startActivity()方法完成Activity的启动。ActivityManagerNative继承自Binder并实现了IActivityManager这个Binder接口,ActivityManagerNative.getDefault()方法如下所示

static public IActivityManager getDefault() {
    
    
        return gDefault.get();
    }
    
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;
        }
    };

ActivityManagerNative.getDefault()方法返回的其实是一个IActivityManager类型的Binder对象,它的具体实现类是ActivityManagerService,且ActivityManagerService也是一个Binder对象。其ActivityManagerService(AMS)这个对象采用单列模式对外提供,Singleton是一个单列的封装类,在第一次调用它的get方法时会通过creat方法初始化AMS这个Binder对象,在后续的调用中则直接返回之前创建的对象。
根据上面的分析可知 ActivityManagerNative.getDefault().startActivity()方法实际上是调用了AMS.startActivity()方法。AMS.startActivity()代码如下

@Override
 public final int startActivity(IApplicationThread caller, String callingPackage,
           Intent intent, String resolvedType, IBinder resultTo,
           String resultWho, int requestCode, int startFlags,
           String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
    
    
     return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                                resultWho, requestCode, startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
 }
  
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
         Intent intent, String resolvedType, IBinder resultTo,
         String resultWho, int requestCode, int startFlags,
         String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
    
    
    enforceNotIsolatedCaller("startActivity");
    userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
             false, true, "startActivity", null);
     // TODO: Switch to user app stacks here.
    return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
            resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
             null, null, options, userId);
}

其主要执行逻辑为调用mStackSupervisor.startActivityMayWait()方法,类ActivityStackSupervisor是用来辅助ActivityManagerService对Activity和Task的管理的。调用mStackSupervisor.startActivityMayWait()函数后,会执行下面几个函数,调用关系参照时序图,函数里涉及很多细节,这里只简单描述下它们的主要功能:

  1. ActivityStackSupervisor.startActivityLocked(): 检查启动权限,创建新的ActivityRecord。
  2. ActivityStackSupervisor.startActivityUncheckedLocked():处理intent携带的launch flags, launchMode。
  3. ActivityStack.startActivityLocked():将activity放到所属task的顶部,重置Task(resetTaskIfNeededLocked),调用WindowManager.setAppStartingWindow()。
  4. ActivityStackSupervisor.resumeTopActivitiesLocked():判断ActivityStack数组中是否存在target ActivityStack。
  5. ActivityStack.resumeTopActivityLocked(): 从当前activity切换到要启动的activity。
  6. ActivityStackSupervisor.startSpecificActivityLocked():获取ProcessRecord(若要启动的activity的应用已经在运行),若获取ProcessRecord存在则调用realStartActivityLocked(),否则调用 ActivityManagerServices.startProcessLocked()创建新的ProcessRecord,最后调用Process.start()启动新的进程(最终调用Zygote启动新的进程,为了避免混淆,这部分在时序图中没有体现,后面再研究)。
  7. ActivityStackSupervisor.realStartActivityLocked(): 调用mWindowManager.setAppVisibility()设置app可见。
  8. ActivityThread.scheduleLauncherActivity(): 发送Message LAUNCH_ACTIVITY给Handler.
    Handler接收到message后,执行ActivityThread.handleLaunchActivity()方法
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    
     
    ......
    Activity a = performLaunchActivity(r, customIntent);  // 返回一个activity.
    if (a != null) {
    
    
        r.createdConfig = new Configuration(mConfiguration);
        Bundle oldState = r.state;
        handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed);
        
        if (!r.activity.mFinished && r.startsNotResumed) {
    
    
            // 当这个activity没有finished而且没有处于resumed状态时,Acivity Manager实际上想要这个activity以paused状态开始,因为它需要可见,但是又不在前台。             // 为此,需要经过正常启动(因为activity希望在它们的window被显示前,它们第一次运行时通过onResume),然后暂停它。The activity manager actually wants this one to start out
            //然而,在这种情况下,不需要走完整的暂停周期(比如freezing等),因为activity假定它可以刚好保留它当前的所有状态。
            try {
    
    
               r.activity.mCalled = false;
               mInstrumentation.callActivityOnPause(r.activity);
               ......
             } catch (SuperNotCalledException e) {
    
    
                 ......
             } catch (Exception e) {
    
    
                 ......
             }
            r.paused = true;
        }
    } else {
    
    
        ......
    }
}

performLaunchActivity方法最终完成了Activity对象的创建和启动过程。
performLaunchActivity()这个方法做了几件重要的事情:创建activity实例,调用Activity.attach()设置参数,触发Activity.onCreate()。
1.从ActivityClientRecord中获取待启动的Activity的组件信息

 ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
    
            // 填充package info
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                                       Context.CONTEXT_INCLUDE_CODE);
    }

    ComponentName component = r.intent.getComponent();
    if (component == null) {
    
    
        component = r.intent.resolveActivity(mInitialApplication.getPackageManager());
        r.intent.setComponent(component);      //设置Component
    }
    if (r.activityInfo.targetActivity != null) {
    
    
        component = new ComponentName(r.activityInfo.packageName,
        r.activityInfo.targetActivity);
    }

2.通过Instrumentation的newActivity方法使用类加载器创建Activity对象

Activity activity = null;
    try {
    
    
        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);    // 根据Activity的类名,通过Java反射机制创建对应的Activity.
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        if (r.state != null) {
    
    
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {
    
    
        ......
    }

3.通过LoadedApk的makeApplication方法来尝试创建Application对象,且一个应用只有一个Application对象。
4.创建ContextImpl对象并通过Activity的attach方法来完成一些重要的数据的初始化,ContextImpl是一个很重要的数据结构,它是Context的具体实现,Context中大部分逻辑是由ContextImpl来完成的。ContextImpl是通过Activity的attch方法来和Activity建立关联的,除此之外,在attach方法中activity还会完成window的创建并建立自己和window的关联,这样当window接收外部输入事件后就可以将事件传递给Activity
5.调用Activity的onCreat方法
由于Activity的onCreat()已经被调用,这就意味着Activity已经完成了整个启动过程。

总结

猜你喜欢

转载自blog.csdn.net/qq_30193541/article/details/108219783