Activity的工作过程

本文详细剖析了Android中Activity的启动过程,从startActivity方法入手,深入探讨了Instrumentation、ActivityThread、ActivityManagerService等核心组件的作用,以及它们如何协同工作来启动一个Activity。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一、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已经完成了整个启动过程。

总结

### 回答1: activity是Android中的一个组件,用于构建用户界面和处理用户交互。其工作流程如下: 1. 创建activity:当用户启动应用程序或从其他activity转换到当前activity时,系统会创建一个新的activity实例。 2. 加载布局:activity创建后,系统会加载与之关联的布局文件,并将其显示在屏幕上。 3. 处理用户交互:用户与activity交互时,系统会调用相应的回调方法,例如onCreate、onStart、onResume等。 4. 处理生命周期:当用户离开当前activity或者屏幕被覆盖时,系统会调用相应的回调方法,例如onPause、onStop、onDestroy等。 5. 保存和恢复状态:当activity被销毁并重新创建时,系统会保存和恢复其状态,以确保用户体验的连续性。 总之,activity是Android应用程序中最重要的组件之一,负责处理用户界面和用户交互,同时也需要处理生命周期和状态保存等问题。 ### 回答2: activity工作流程是指在软件开发过程中,将一个复杂的业务流程拆分成一系列的简单的活动或任务,并通过定义这些活动之间的逻辑关系,实现任务的协作和执行。 首先,需要明确定义业务流程的目标和要求。然后,通过业务分析,将业务流程拆分成各个子任务或活动,并确定它们的执行顺序和依赖关系。 接下来,需要对每个活动进行详细设计和实现。这包括确定活动的输入和输出,定义活动所需的资源和工具,以及编写执行该活动的代码。 在实际执行过程中,根据活动之间的关系,可以采用串行、并行或条件分支的方式来组织活动的执行顺序。每个活动在执行时,需要根据预设条件进行判断,确定是否满足执行条件。如果满足条件,则执行该活动;如果不满足条件,则等待条件满足后再执行。 在活动执行过程中,还需要及时记录活动的执行结果和状态,并根据需要进行相应的处理。如果某个活动执行失败,可以根据事先定义的异常处理策略,进行异常处理,并进行相应的后续操作。 最后,根据整个业务流程的执行结果,进行相应的汇总和统计,并输出相应的报告或结果。 总结来说,activity工作流程是通过将复杂的业务流程拆分成若干个简单的活动,并通过定义它们之间的逻辑关系和执行顺序,实现业务流程的自动化执行和协作。它可以提高工作效率,减少人为操作的错误,并方便对业务流程进行管理和监控。 ### 回答3: Activity工作流程是一种流行的、灵活的工作流程管理框架。它适用于各种类型的应用程序,包括企业、电子商务和科学应用。下面是Activity工作流程的详细解释。 Activity工作流程由一系列活动(Activity)组成,这些活动表示可以在应用程序中执行的任务或操作。每个活动都有一个特定的目标,并且通常是按照特定的顺序进行的。 工作流程开始于一个起始活动(Start Activity),表示工作流程的起点。然后,根据定义的规则和条件,系统将根据不同的条件选择执行不同的活动。 在Activity工作流程中,活动可以是串行的(Sequential),也可以是并行的(Parallel)。串行活动按顺序执行,而并行活动可以同时执行。这使得Activity工作流程非常灵活,可以适应各种业务场景的需求。 每个活动都可以定义输入和输出数据,以及执行的规则和条件。这些规则和条件可用于控制工作流程的流转,并在需要时触发特定的行为或决策。 在Activity工作流程中,活动之间可以有依赖关系,也可以有分支和合并。这些依赖关系和控制结构可以用来管理工作流程的执行顺序和条件。例如,如果某个活动的执行条件不满足,工作流程可以跳过该活动并继续执行其他活动。 工作流程的最后一个活动通常是结束活动(End Activity),表示工作流程的终点。当活动执行到结束活动时,工作流程就完成了。 总的来说,Activity工作流程是一种灵活而强大的工作流程管理框架,可以在各种场景中使用。它的特点包括定义明确的活动、支持串行和并行执行、具有条件和规则控制等。通过使用Activity工作流程,可以更加有效地管理和执行复杂的业务流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值