android启动过程activity启动源码分析(activitythread流程分析一)(代码片段)

韩曙亮 韩曙亮     2023-01-03     463

关键词:





一、ActivityThread 主函数启动



ActivityThread 是应用的主线程 , 从 main 函数开始执行 ;

Looper.prepareMainLooper() 将主线程设置为 Looper 线程 , 开启 Looper , 用于配合 H 处理消息 ;

thread.attach(false, startSeq) 绑定 ActivityThread ;

在方法最后 Looper.loop(); 开始无限循环 , 处理 Handler 消息 ;

/**
 * 管理应用程序进程中主线程的执行、调度和执行活动、广播以及活动管理器请求的其他操作。
 *
 * @hide
 */
public final class ActivityThread extends ClientTransactionHandler 
    public static void main(String[] args) 

		// 将主线程设置为 Looper 线程 , 开启 Looper , 用于配合 H 处理消息 
        Looper.prepareMainLooper();

		// 创建 ActivityThread 实例对象 
        ActivityThread thread = new ActivityThread();
        // 绑定
        thread.attach(false, startSeq);
	
		// 开始无限循环 , 处理 Handler 消息 
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    

完整代码参考 /frameworks/base/core/java/android/app/ActivityThread.java





二、ActivityThread 绑定 ApplicationThread



ActivityThread 中的 void attach(boolean system, long startSeq) 方法 , 主要是通过 Binder 机制获取 AMS , 并调用 AMS 的 attachApplication 方法 , 为 ActivityThread 绑定 ApplicationThread ;

/**
 * 管理应用程序进程中主线程的执行、调度和执行活动、广播以及活动管理器请求的其他操作。
 *
 * @hide
 */
public final class ActivityThread extends ClientTransactionHandler 

    private void attach(boolean system, long startSeq) 
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) 
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            // 通过 Binder 机制获取 AMS 
            final IActivityManager mgr = ActivityManager.getService();
            try 
            	// 调用 AMS 的 attachApplication 方法 , 为 ActivityThread 绑定 ApplicationThread 
                mgr.attachApplication(mAppThread, startSeq);
             catch (RemoteException ex) 
                throw ex.rethrowFromSystemServer();
            
        
    


完整代码参考 /frameworks/base/core/java/android/app/ActivityThread.java





三、AMS attachApplication -> attachApplicationLocked 绑定 ApplicationThread



在 AMS 中的 attachApplication 方法中 , 调用了 attachApplicationLocked 方法 ,

attachApplicationLocked 方法中 , 有调用了 ActivityThread 的 bindApplication 方法 , 为 ActivityThread 绑定了 ApplicationThread ;

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback 

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


	// 为 ApplicationThread 绑定 Application 主方法
    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) 
        try 
            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
            mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
			// 在此处为 ActivityThread 绑定 Application , 此时又回到 ActivityThread
            if (app.instr != null) 
                thread.bindApplication(processName, appInfo, providers,
                        app.instr.mClass,
                        profilerInfo, app.instr.mArguments,
                        app.instr.mWatcher,
                        app.instr.mUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);
             else 
                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);
            
         catch (Exception e) 
        

        return true;
    


ActivityManagerService 完整源码参考 : frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java





四、ApplicationThread.bindApplication 绑定 ApplicationThread



再次回到 ActivityThread 内部类 ApplicationThread 中 , 调用 ApplicationThread 类的 bindApplication 方法 , 即可为 ActivityThread 绑定 ApplicationThread , 在所有数据就位后 , 发送了一个 H.BIND_APPLICATION 消息 ;

/**
 * 管理应用程序进程中主线程的执行、调度和执行活动、广播以及活动管理器请求的其他操作。
 *
 * @hide
 */
public final class ActivityThread extends ClientTransactionHandler 
    private class ApplicationThread extends IApplicationThread.Stub 
		// 为 ActivityThread 绑定 Application 
        public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo> providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                String buildSerial, boolean autofillCompatibilityEnabled) 

            // 此处在所有数据就位后 , 发送了一个 H.BIND_APPLICATION 消息
            sendMessage(H.BIND_APPLICATION, data);
        
	

完整代码参考 /frameworks/base/core/java/android/app/ActivityThread.java





五、ActivityThread.H 处理 BIND_APPLICATION 消息



ActivityThread.ApplicationThread.bindApplication 中 , 发送了一条 BIND_APPLICATION 消息 , 110 110 110 ;

ActivityThread.H 中的 handleMessage 方法中 , 处理 110 110 110 事件的分支中, 调用了 handleBindApplication 方法 , 处理绑定 ApplicationThread 相关逻辑 ;

/**
 * 管理应用程序进程中主线程的执行、调度和执行活动、广播以及活动管理器请求的其他操作。
 *
 * @hide
 */
public final class ActivityThread extends ClientTransactionHandler 
    class H extends Handler 
        public static final int BIND_APPLICATION        = 110;

        public void handleMessage(Message msg) 
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) 
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    // 处理绑定 Application 相关逻辑
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
            
            Object obj = msg.obj;
            if (obj instanceof SomeArgs) 
                ((SomeArgs) obj).recycle();
            
        
    

完整代码参考 /frameworks/base/core/java/android/app/ActivityThread.java





六、ActivityThread.handleBindApplication 处理绑定问题



ActivityThread.handleBindApplication 方法中 , 通过调用 data.info.makeApplication(data.restrictedBackupMode, null) 方法 , 创建 Application 实例对象 ;

data.infoLoadedApk 类型 ;

/**
 * 管理应用程序进程中主线程的执行、调度和执行活动、广播以及活动管理器请求的其他操作。
 *
 * @hide
 */
public final class ActivityThread extends ClientTransactionHandler 
    private void handleBindApplication(AppBindData data) 
        // 将UI线程注册为运行时的敏感线程。
        VMRuntime.registerSensitiveThread();
        if (data.trackAllocation) 
            DdmVmInternal.enableRecentAllocations(true);
        

        // 记录进程开始时间
        Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());

        // 允许在应用程序和提供程序安装期间访问磁盘。
        // 这可能会阻止处理有序的广播,但稍后的处理可能最终会执行相同的磁盘访问。
        Application app;
        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
        final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();
        try 
            // 如果要启动应用程序进行完全备份或恢复,请使用基本应用程序类在受限环境中启动。
            app = data.info.makeApplication(data.restrictedBackupMode, null);

            // Propagate autofill compat state
            app.setAutofillCompatibilityEnabled(data.autofillCompatibilityEnabled);

            mInitialApplication = app;
         
    

完整代码参考 /frameworks/base/core/java/android/app/ActivityThread.java





七、LoadedApk.makeApplication 创建 Application 对象



调用 LoadedApkmakeApplication 方法 , 创建 Application 实例 , 在该方法中通过调用 InstrumentationnewApplication 方法 , 创建 Application 实例对象

/**
 * 本地状态维护了当前加载的.apk. 
 * Local state maintained about a currently loaded .apk.
 * @hide
 */
public final class LoadedApk 

	// 创建 Application 实例对象 
    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) 
        // 如果当前存在 Application , 直接返回 
        if (mApplication != null) 
            return mApplication;
        

        try 
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            // 通过调用 Instrumentation 的 newApplication 方法 , 创建 Application 实例对象
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
         catch (Exception e) 
        
        mActivityThread.mAllApplications.add(app);
        mApplication = app;

        return app;
    

完整代码参考 /frameworks/base/core/java/android/app/LoadedApk.java ;





八、Instrumentation.newApplication 创建 Application 对象



LoadedApkmakeApplication 方法 中 , 调用了 InstrumentationnewApplication 方法创建 Application 实例对象 ;

/**
 * 用于实现应用程序检测代码的基类。
 * 当在启用检测的情况下运行时,该类将在任何应用程序代码之前为您实例化,
 * 从而允许您监视系统与应用程序之间的所有交互。
 * 通过AndroidManifest.xml的&amp;lt;仪器仪表&amp;gt;标签。
 */
public class Instrumentation 

    /**
     * 执行进程@link Application对象的实例化。默认实现提供正常的系统行为。
     *
     * @param cl 用来实例化对象的类加载器。
     * @param className 实现应用程序对象的类的名称。
     * @param context 用于初始化应用程序的上下文
     *
     * @return 新实例化的应用程序对象。
     */
    public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException 
        Application app = getFactory(context.getPackageName())
                .instantiateApplication(cl, className);
        app.attach(context);
        return app;
    
	

完整代码参考 /frameworks/base/core/java/android/app/Instrumentation.java ;





九、AppComponentFactory.instantiateApplicationCompat 创建 Application 对象



InstrumentationnewApplication 方法中 , 调用了 AppComponentFactoryinstantiateApplicationCompat 方法 , 创建 Application , (Application) cl.loadClass(className).getDeclaredConstructor().newInstance(); , 此处通过反射创建 Application 实例对象 ;

/**
 * 使用androidx库的@link android.app.AppComponentFactory版本。
 *
 * 注意:这只适用于API 28+,不支持AppComponentFactory功能。
 */
@RequiresApi(28)
public class AppComponentFactory extends android.app.AppComponentFactory 

   /**
    * 允许应用程序重写应用程序对象的创建。这可以用于对这些类执行依赖项注入或类装入器更改等操作。
    * <p>
    * 此方法仅用于提供用于实例化的挂钩。它不提供对应用程序对象的早期访问。
    * 返回的对象尚未初始化为上下文,不应用于与其他android API交互。
    *
    * @param cl        用于实例化的默认类加载器。
    * @param className 要实例化的类。
    */
    public @NonNull Application instantiateApplicationCompat(@NonNull ClassLoader cl,
            @NonNull String className)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException 
        try 
            return (Application) cl.loadClass(className).getDeclaredConstructor().newInstance();
         catch (InvocationTargetException | NoSuchMethodException e) 
            throw new RuntimeException("Couldn't call constructor", e);
        
    


完整代码参考 /frameworks/support/compat/src/main/java/androidx/core/app/AppComponentFactory.java ;

android6.0源码分析之activity启动过程

Activity最为android开发者最熟悉的组件,由ActivityManagerService服务进行调度管理,而ActivityManagerService的启动过程在activitymanagerservice服务源码分析一文中进行了详细分析,本文基于其对Activity的启动过程进行分析,同... 查看详情

android启动过程activity启动源码分析(ams->activitythreadams线程阶段)(代码片段)

文章目录一、Activity启动源码分析(AMS|ActivityManagerService)1、Instrumentation调用AMS方法2、ActivityStarter调用AMS方法3、Process启动新进程二、Activity启动源码分析(ActivityStarter)1、ActivityStarter.startActivityMayWait()方法2、ActivityStart 查看详情

android启动过程activity启动源码分析(ams->activitythreadams线程阶段二)(代码片段)

...r机制转到ActivityThread中执行的操作总结前言上一篇博客【Android启动过程】Activity启动源码分析(AMS->ActivityThread、AMS线程阶段)分析的分支是启动Activity时,没有Activity对应的进程,需要先调用Zygote启动相应进程,然后再启动Activ 查看详情

android启动过程activity启动源码分析(activitythread流程分析一)(代码片段)

文章目录一、ActivityThread主函数启动二、ActivityThread绑定ApplicationThread三、AMSattachApplication->attachApplicationLocked绑定ApplicationThread四、ApplicationThread.bindApplication绑定ApplicationThread五、ActivityThread. 查看详情

android启动过程activity启动源码分析(activitythread->activity主线程阶段一)(代码片段)

文章目录前言一、ClientTransactionHandler.scheduleTransaction二、ActivityThread.H处理EXECUTE_TRANSACTION消息三、TransactionExecutorexecute->executeCallbacks方法四、LaunchActivityItem.execute总结前言上一篇博客【Android启动过程】Activi 查看详情

android启动过程activity启动源码分析(activitythread->activity主线程阶段二)(代码片段)

文章目录前言一、ActivityThread类handleLaunchActivity->performLaunchActivity方法二、Instrumentation.newActivity方法三、AppComponentFactory.instantiateActivityCompat方法四、ActivityThread.performLaunchActivity方法后续细节五、Ins 查看详情

android6.0源码分析之activity启动过程

Activity最为android开发者最熟悉的组件,由ActivityManagerService服务进行调度管理,而ActivityManagerService的启动过程在activitymanagerservice服务源码分析一文中进行了详细分析,本文基于其对Activity的启动过程进行分析,同... 查看详情

基于android10.0源码分析activity的启动流程(代码片段)

一、梳理源码流程干什么Activity是四大组件中最重要的组件之一,下面来分析Activity的启动过程,了解Activity的启动过程能帮助我们更好的对组件Activity的理解,也能帮助我们更好的把控Activity生命周期的变化过程。当... 查看详情

基于android10.0源码分析activity的启动流程(代码片段)

一、梳理源码流程干什么Activity是四大组件中最重要的组件之一,下面来分析Activity的启动过程,了解Activity的启动过程能帮助我们更好的对组件Activity的理解,也能帮助我们更好的把控Activity生命周期的变化过程。当... 查看详情

android应用启动流程分析(代码片段)

1前言网上看过很多Activity启动过程的源码解析,很多文章会贴上一大段代码,然后从startActivity()函数开始深究整个源码的调用栈。个人感觉这类文章代码细节太多,反而容易迷失在源码调用之中,从而忽略了Activit... 查看详情

activity启动过程——10.0源码分析(代码片段)

对于一个activity,注意不是根activity,它的启动流程往往是通过创建intent,通过startActivity()的方式启动的,我们跟踪的就是安卓10.0这部分的启动流程。在windows系统看,看源码可以通过源码阅读 这个网址查看&#x... 查看详情

android应用启动流程分析(代码片段)

1前言网上看过很多Activity启动过程的源码解析,很多文章会贴上一大段代码,然后从startActivity()函数开始深究整个源码的调用栈。个人感觉这类文章代码细节太多,反而容易迷失在源码调用之中,从而忽略了Activit... 查看详情

android源码分析startservice启动(代码片段)

startService启动过程ContextImpl到AMS的调用过程当我们在Activity中调用startActivity函数的时候,点击startActivity看源码实现会发现它是在ContextWrapper类中实现的。我们继续看Context的startService实现,代码如下://Context.javapublicabstractcla... 查看详情

android源码分析startservice启动(代码片段)

startService启动过程ContextImpl到AMS的调用过程当我们在Activity中调用startActivity函数的时候,点击startActivity看源码实现会发现它是在ContextWrapper类中实现的。我们继续看Context的startService实现,代码如下://Context.javapublicabstractcla... 查看详情

android源码分析activity启动(代码片段)

Android 启动类的作用Instrumentation    完成对Application和Activity初始化和生命周期调用的工具类。用来监控系统与应用的交互。ActivityThread    管理应用进程的主线程的执行。ApplicationThread    用来实现ActivityManagerService与ActivityT... 查看详情

activity启动过程——10.0源码分析(代码片段)

对于一个activity,注意不是根activity,它的启动流程往往是通过创建intent,通过startActivity()的方式启动的,我们跟踪的就是安卓10.0这部分的启动流程。在windows系统看,看源码可以通过源码阅读 这个网址查看&#x... 查看详情

androidactivity——启动过程探索(代码片段)

《Android自定义View之Activity页面的组成》《AndroidActivity——启动过程探索(一)》《AndroidActivity——启动过程探索(二)》《AndroidActivity——启动过程探索(三)》《Activity启动模式及任务栈探究》《Activity... 查看详情

app启动过程(含activity启动过程)|安卓offer收割基

...: 布兰柯基本文链接: https://blankj.com/2018/12/18/android-adapt-screen-killer/618,祝大家购物愉快,文末有彩蛋~~这道题在曾经面试「菜鸟网络」中遇到过,不过当时只问了「Activity启动过程」,这里对整个「App启... 查看详情