当前位置:   article > 正文

AMS(ActivityManagerService)源码解析2,Android应用是如何被启动的

AMS(ActivityManagerService)源码解析2,Android应用是如何被启动的

前言

基于源码API 28,30以后的版本启动第一个Activity的逻辑不一样

我会只拿出我们需要关注的代码部分,因为源码太多全都看看不过来的。所以每次截代码都有省略
前言
源码只截取需要看的部分,其他部分会省略。

源码基于API 28也就是Android9.0,也就是源码还有ActivityStackSupervisor的这个版本
其他版本代码不太一样没有ActivityStackSupervisor,但是原理是相同的。

AOSP的源码在这个网站上看:http://aospxref.com/

总结

用流程总结app启动:

  1. 用户点击应用图标(或者其他方式打开app)
  2. 要打开app的进程(可能是桌面进程可能是别的Intent)通知zygote进程fork出一个新的进程用于承载app。
  3. ActivityThread通过main方法启动,通过跨进程通信,通知SystemServer进程
  4. SystemServer的AMS去找PMS拿对应的进程信息。
  5. AMS将进程信息PackageInfo返还给应用进程
  6. ActivityThread创建Instrumentation和通过反射的方式创建Application,
  7. Instrumentation调用application的生命周期。

用流程总结第一个Activity启动:

  1. AMS遍历mPackages里面的Activity标签之后,找到启动时所需要的那个Activity(根据Intent里面的那个启动标签)。
  2. 准备一个事务(clientTransaction),里面包括了Activity的启动(Callback)和拉到前台(lifecycleState)两件事。

后面的流程参考上一篇文章的第六节,我们只需要知道一旦往ActivityThread发了一个ClientTransaction之后,后面的流程就完全是固定的。

AMS(ActivityManagerService)源码解析,Activity是如何被打开的
https://blog.csdn.net/qq_41872247/article/details/125031721

1. 启动Application

1.1 拉起一个新的进程

首先我们需要明确一点的是,启动一个app,他的起点来自于桌面进程,桌面进程在用户点击app图标准备拉起app的时候,就会让Zygote进程去即使的fork一个新的app进程出来,然后寻找到这个新的app的ActivityThread类的Main方法进行执行。

这部分见https://blog.csdn.net/qq_41872247/article/details/125211491

1.2 启动Application

接下来我们就来到了ActivityThread的Main方法

public final class ActivityThread extends ClientTransactionHandler
        implements ActivityThreadInternal {

	private ApplicationThread mAppThread
        
    // 启动类
    public static void main(String[] args) {
		ActivityThread thread = new ActivityThread();
		thread.attach(false, startSeq);
	}

	private void attach(boolean system, long startSeq) {
		if(!system) {
			final IActivityManager mgr = ActivityManager.getService();
	        try {
	            mgr.attachApplication(mAppThread, startSeq);
	        } catch (RemoteException ex) {
	            throw ex.rethrowFromSystemServer();
	        }
        }
	}

	private class ApplicationThread extend IApplicationThread.Stub {}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

到attach,我们就通过跨进程进行binder通信了,拿到了AMS对象。我们传的对象ApplicationThread就是ActivityThread的一个内部类,持有外部引用,这个类就是负责和AMS通信。

1.3 AMS阶段

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    public final void attachApplication(IApplicationThread thread, long startSeq) {
    	synchronized (this) {
    		attachApplicationLocked(thread, callingPid, callingUid, startSeq);
    	}
    }

	private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
		
		ProcessRecord app;
		
		// 这段代码从PMS中请求App的数据
		if (app == null && startSeq > 0) {
            final ProcessRecord pending = mPendingStarts.get(startSeq);
            if (pending != null && pending.startUid == callingUid && pending.startSeq == startSeq
                    && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
                            startSeq, true)) {
                app = pending;
            }
        }
        
        if (app.isolatedEntryPoint != null) {
                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
            } else 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, isAutofillCompatEnabled);
            } 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, isAutofillCompatEnabled);
            }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

AMS这部分先去PMS里面拿到当前app的相关数据(之前写在AndroidManifest里面的解析后存在mPackages的内容),
然后再返回来给ApplicationThread(走到thread.bindApplication)。

1.4 创建Instrumentation和Application

public final class ActivityThread extends ClientTransactionHandler
        implements ActivityThreadInternal {
   
   private class ApplicationThread extend IApplicationThread.Stub {

		public final void bindApplication(很多入参) {
			AppBindData data = new AppBindData();
			// ....将App的数据都放进data里面
			sendMessage(H.BIND_APPLICATION, data);
		}
   }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

这里第一次sendMsg了,就是handler的那套流程,最后走到的是外侧的一个bindApplication方法

public final class ActivityThread extends ClientTransactionHandler
        implements ActivityThreadInternal {
        
	private static class AndroidOs extends ForwardingOs {
	
		private void handleBindApplication(AppBindData data) {
			// 一般都是走上面
			if (ii != null) {
	            initInstrumentation(ii, data, appContext);
	        } else {
	            mInstrumentation = new Instrumentation();
	            mInstrumentation.basicInit(this);
	        }
			//.....省略无关代码
            Application app;
			try {
				// 创建appllication
				app = data.info.makeApplicationInner(data.restrictedBackupMode, null);
				//......
				// Instrumentation自己的onCreate方法,等于自己的生命周期,忽视它
				mInstrumentation.onCreate(data.instrumentationArgs);
				//......
                mInstrumentation.callApplicationOnCreate(app);
            }
		}

		private void initInstrumentation(
            InstrumentationInfo ii, AppBindData data, ContextImpl appContext) {
            
            try {
	            final ClassLoader cl = instrContext.getClassLoader();
	            mInstrumentation = (Instrumentation)
	                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
        	}
        	//init只是把一大堆东西给他赋值到成员变量里面
        	mInstrumentation.init(this, instrContext, appContext, component,
                data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
	        }
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

他在这段代码中做了几件事:

  1. 创建Instrumentation对象
  2. 创建Application对象
  3. 调用Application的生命周期

Instrumentation的创建过程上面已经有了,接下来看makeApplicationInner是如何创建Application的:

public final class LoadedApk {
	private Application makeApplicationInner(boolean forceDefaultAppClass,
            Instrumentation instrumentation, boolean allowDuplicateInstances) {
        Application app = null;
        app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
        return app;
    }
}

public class Instrumentation {
	public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        // getFactory我们具体就不看了,最终就是返回一个AppComponentFactory的对象
        Application app = getFactory(context.getPackageName())
                .instantiateApplication(cl, className);
        app.attach(context); //这个attach,就是我们自己定义的Application类的生命周期的那个attach,由Instrumentation直接调用
        return app;
    }
}

public class AppComponentFactory {
	public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
            @NonNull String className)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        // 走到最后还是反射创建的对象。
        return (Application) cl.loadClass(className).newInstance();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

虽然中间跨了很多个类,但是还是可以看得出来根本的那行代码还是反射创建Application对象。

最后看看Application的生命周期是如何被Instrumentation调用的

public class Instrumentation {
    public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5

结果就是直接调用,没有任何转折。

2. 启动Activity

2.1 回到AMS,启动第一个Activity

  1. 代码回到AMS,刚刚AMS的代码还未执行完。
public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
        
    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
        //.. bind之后发生的事

		// See if the top visible activity is waiting to run in this process...
		// 查看在这个进程中顶部的Activity是否正在等待运行...   其实就是启动顶部Activity了
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
	}
}

public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener,
        RecentTasks.Callbacks {
	boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = display.getChildAt(stackNdx);
                if (!isFocusedStack(stack)) {
                    continue;
                }
                stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
                final ActivityRecord top = stack.topRunningActivityLocked();
                final int size = mTmpActivityList.size();
                for (int i = 0; i < size; i++) {
                    final ActivityRecord activity = mTmpActivityList.get(i);
                    if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                            && processName.equals(activity.processName)) {
                        try {
                        	// 通过好几层的for循环遍历app里面所有的Activity,去寻找并启动app的启动页
                            if (realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                           
                            throw e;
                        }
                    }
                }
            }
        }
        if (!didSomething) {
            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        }
        return didSomething;
    }


	final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
        try {
			// 准备启动Activity的事务
            final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                    r.appToken);
            // 这里准备了一个LaunchActivityItem作为Callback,记住他,后面会用到
            clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                    System.identityHashCode(r), r.info,
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                    profilerInfo));

            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {
            	// 这里我们是启动Activity,所以走resume
                lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            // 这里准备了一个ResumeActivityItem作为LifecycleState,记住他,后面会用到
            clientTransaction.setLifecycleStateRequest(lifecycleItem);

			// 发送这个事务
			mService.getLifecycleManager().scheduleTransaction(clientTransaction);
            }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92

AMS遍历了一下启动进程的所有Activity,找到启动时要用的那个,走到了realStartActivityLocked准备启动。

后面的流程参考这篇文章的第六节,是完全一样的
AMS(ActivityManagerService)源码解析,Activity是如何被打开的
https://blog.csdn.net/qq_41872247/article/details/125031721

参考资料

码牛学院VIP课程 VIP12-2021.12.03-這染机制-01 Activity. View. WMS的协调kerwin

AOSP的源码网站:http://aospxref.com/

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/736924
推荐阅读
相关标签
  

闽ICP备14008679号