Framework学习(五)应用程序启动过程(1)

intent.prepareToLeaveProcess(who);

//1

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 RuntimeException("Failure from system", e);

}

return null;

}

注释1首先调用ActivityManagerNative的getDefault来获取ActivityManageService(以后简称为AMS)的代理对象,接着调用它的startActivity方法。

这里ActivityManagerNative.getDefault()涉及到Binder进程间通信机制,下面进行一个简短的介绍,这不是本文的重点。了解过的同学可以略过下面这段Binder简析,不想了解的也可以直接理解为返回的是AMS。实际调用的是AMS#startActivity()。

AMS中Binder机制简析

frameworks/base/core/java/android/app/ActivityManagerNative.java

ActivityManagerNative.getDefault()

static public IActivityManager getDefault() {

return gDefault.get();

}

private static final Singleton gDefault = new Singleton() {

protected IActivityManager create() {

IBinder b = ServiceManager.getService("activity"); //1

IActivityManager am = asInterface(b); //2

return am;

}

};

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);

}

getDefault方法调用了gDefault的get方法,gDefault 是一个Singleton类。注释1处得到名为"activity"的Service代理对象,也就是AMS的代理对象。

注释2处将它封装成ActivityManagerProxy(以后简称为AMP)类型对象,并将它保存到gDefault中,此后调用ActivityManagerNative(以后简称为AMN)的getDefault方法就会直接获得AMS的代理AMP对象。

回到Instrumentation类的execStartActivity方法中,从上面得知就是调用AMP的startActivity,其中AMP是AMN的内部类,代码如下所示。

frameworks/base/core/java/android/app/ActivityManagerNative.java

ActivityManagerProxy#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); //1

reply.readException();

int result = reply.readInt();

reply.recycle();

data.recycle();

return result;

}

首先会将传入的参数写入到Parcel类型的data中。在注释1处通过IBinder对象mRemote向AMN发送一个START_ACTIVITY_TRANSACTION类型的进程间通信请求。那么服务端AMN就会从Binder线程池中读取我们客户端发来的数据,最终会调用AMN的onTransact方法中执行。

ActivityManagerNative#onTransact()

@Override

public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {

switch (code) {

case START_ACTIVITY_TRANSACTION:

{

...

int result = startActivity(app, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, options); //1

reply.writeNoException();

reply.writeInt(result);

return true;

}

}

因为AMS继承了AMN,服务端真正的实现是在AMS中,注释1最终会调用AMS的startActivity方法。

ActivityManagerService#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 bOptions) {

return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId()); //1

}

AMS中Binder机制暂且分析到这里。

下面看从Launcher到AMS的时序图:

AMS到ActivityThread的调用流程

上面注释1处调用了AMS的startActivityAsUser方法。

ActivityManagerService#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 bOptions, int userId) {

enforceNotIsolatedCaller("startActivity");

userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "startActivity", null);

// TODO: Switch to user app stacks here.

//1

return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, bOptions, false, userId, null, null);

}

注释1处调用了ActivityStarter的startActivityMayWait方法。

frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

ActivityStarter#startActivityMayWait()

final int startActivityMayWait(IApplicationThread caller, int callingUid,String callingPackage, Intent intent, String resolvedType,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,IBinder resultTo, String resultWho, int requestCode, int startFlags,ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,Bundle bOptions, boolean ignoreTargetSecurity, int userId,IActivityContainer iContainer, TaskRecord inTask) {

...

doPendingActivityLaunchesLocked(false); //1

...

return err;

}

注释1调用了doPendingActivityLaunchesLocked方法。

ActivityStarter#doPendingActivityLaunchesLocked()

final void doPendingActivityLaunchesLocked(boolean doResume) {

while (!mPendingActivityLaunches.isEmpty()) {

final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);

final boolean resume = doResume && mPendingActivityLaunches.isEmpty();

try {

//1

final int result = startActivityUnchecked(pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null, null);

postStartActivityUncheckedProcessing(pal.r, result, mSupervisor.mFocusedStack.mStackId, mSourceRecord, mTargetStack);

} catch (Exception e) {

Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);

pal.sendErrorResult(e.getMessage());

}

}

}

注释1处调用startActivityUnchecked方法。

ActivityStarter#startActivityUnchecked()

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,

IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,

int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {

...

if (mDoResume) {

mSupervisor.resumeFocusedStackTopActivityLocked(); //1

}

...

return START_SUCCESS;

}

注释1处调用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法。

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

ActivityStackSupervisor#resumeFocusedStackTopActivityLocked()

boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

if (targetStack != null && isFocusedStack(targetStack)) {

return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); //1

}

final ActivityRecord r = mFocusedStack.topRunningActivityLocked();

if (r == null || r.state != RESUMED) {

mFocusedStack.resumeTopActivityUncheckedLocked(null, null);

}

return false;

}

注释1处调用了ActivityStack的resumeTopActivityUncheckedLocked方法。

frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

ActivityStack#resumeTopActivityUncheckedLocked()

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {

...

boolean result = false;

try {

// Protect against recursion.

mStackSupervisor.inResumeTopActivity = true;

if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {

mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;

mService.updateSleepIfNeededLocked();

}

result = resumeTopActivityInnerLocked(prev, options); //1

} finally {

mStackSupervisor.inResumeTopActivity = false;

}

return result;

}

注释1处调用resumeTopActivityInnerLocked函数。

ActivityStack#resumeTopActivityInnerLocked()

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {

...

// If the top activity is the resumed one, nothing to do.

if (mResumedActivity == next && next.state == ActivityState.RESUMED &&

mStackSupervisor.allResumedActivitiesComplete()) {

...

return false;

}

if (mResumedActivity != null) {

if (DEBUG_STATES) Slog.d(TAG_STATES,

"resumeTopActivityLocked: Pausing " + mResumedActivity);

pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause); //1

}

...

mStackSupervisor.startSpecificActivityLocked(next, true, false); //2

if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();

...

这个方法里面的内容很多。

注释1主要作用是将mResumedActivity暂停(Launcher任务栈的TopActivity),即进入onPause状态。

注释2调用了ActivityStackSupervisor的startSpecificActivityLocked函数启动指定的AttivityRecored。

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

ActivityStackSupervisor#startSpecificActivityLocked()

void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {

//1

ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true);

r.task.stack.setLaunchTime®;

if (app != null && app.thread != null) {

try {

if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) {

app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, mService.mProcessStats);

}

realStartActivityLocked(r, app, andResume, checkConfig); //2

return;

} catch (RemoteException e) {

Slog.w(TAG, "Exception when starting activity " + r.intent.getComponent().flattenToShortString(), e);

}

}

//3

mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true);

}

ActivityStackSupervisor#getProcessRecordLocked()

final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {

if (uid == Process.SYSTEM_UID) {

// The system gets to run in any process. If there are multiple

// processes with the same uid, just pick the first (this

// should never happen).

SparseArray procs = mProcessNames.getMap().get(processName);

if (procs == null) return null;

...

}

...

}

注释1处获取当前Activity所在的进程的ProcessRecord,如果进程已经启动了,会执行注释2处的代码。否则执行注释3的代码。

注释2处调用realStartActivityLocked来启动应用程序。

注释3处调用AMS的startProcessLocked来启动应用程序进程,注意这里是应用程序进程,只有应用程序进程起来了,才能起应用程序。关于应用程序进程的启动我们可以看Framework学习(六)应用程序进程启动过程这篇文章。

ActivityStackSupervisor#realStartActivityLocked()

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {

...

//1

app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode®, r.info, new Configuration(mService.mConfiguration), new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume,mService.isNextTransitionForward(), profilerInfo);

...

return true;

}

这里的app.thread指的是IApplicationThread,它的实现是ActivityThread的内部类ApplicationThread,其中ApplicationThread继承了ApplicationThreadNative,而ApplicationThreadNative继承了Binder并实现了IApplicationThread接口。

下面看从AMS到ApplicationThread的时序图:

ActivityThread启动Application和Activity

在应用程序进程启动时会创建ActivityThread实例。ActivityThread作为应用程序进程的核心类,它是如何启动应用程序(Activity)的呢?

根据上文接着查看ApplicationThread的scheduleLaunchActivity方法:

frameworks/base/core/java/android/app/ActivityThread.java

ApplicationThread#scheduleLaunchActivity()

@Override

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Configuration curConfig, Configuration overrideConfig,

CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,

int procState, Bundle state, PersistableBundle persistentState,List pendingResults, List pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

updateProcessState(procState, false);

ActivityClientRecord r = new ActivityClientRecord();

r.token = token;

r.ident = ident;

r.intent = intent;

r.referrer = referrer;

r.voiceInteractor = voiceInteractor;

r.activityInfo = info;

r.compatInfo = compatInfo;

r.state = state;

r.persistentState = persistentState;

r.pendingResults = pendingResults;

r.pendingIntents = pendingNewIntents;

r.startsNotResumed = notResumed;

r.isForward = isForward;

r.profilerInfo = profilerInfo;

r.overrideConfig = overrideConfig;

updatePendingConfiguration(curConfig);

sendMessage(H.LAUNCH_ACTIVITY, r); //1

}

会将启动Activity的参数封装成ActivityClientRecord。

注释1处sendMessage方法向H类发送类型为LAUNCH_ACTIVITY的消息,并将ActivityClientRecord 传递过去。

ApplicationThread#sendMessage()

private void sendMessage(int what, Object obj) {

sendMessage(what, obj, 0, 0, false);

}

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {

if (DEBUG_MESSAGES) Slog.v(

TAG, "SCHEDULE " + what + " " + mH.codeToString(what)

  • ": " + arg1 + " / " + obj);
    Message msg = Message.obtain();
    msg.what = what;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    if (async) {
    msg.setAsynchronous(true);
    }
    mH.sendMessage(msg);
    }

这里mH指的是H,它是ActivityThread的内部类并继承Handler。

ActivityThread.H

private class H extends Handler {

public static final int LAUNCH_ACTIVITY = 100;

public static final int PAUSE_ACTIVITY = 101;

...

public void handleMessage(Message msg) {

if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));

switch (msg.what) {

case LAUNCH_ACTIVITY: {

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");

final ActivityClientRecord r = (ActivityClientRecord) msg.obj;//1

r.packageInfo = getPackageInfoNoCheck(

r.activityInfo.applicationInfo, r.compatInfo);//2

handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");//3

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

} break;

...

}

查看H的handleMessage方法中对LAUNCH_ACTIVITY的处理。

注释1处将传过来的msg的成员变量obj转换为ActivityClientRecord。

在注释2处通过getPackageInfoNoCheck方法获得LoadedApk类型的对象并赋值给ActivityClientRecord的成员变量packageInfo 。应用程序进程要启动Activity时需要将该Activity所属的APK加载进来,而LoadedApk就是用来描述已加载的APK文件。

在注释3处调用handleLaunchActivity方法。

ActivityThread#handleLaunchActivity()

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {

...

Activity a = performLaunchActivity(r, customIntent); //1

if (a != null) {

r.createdConfig = new Configuration(mConfiguration);

reportSizeConfigurations®;

Bundle oldState = r.state;

//2

handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

if (!r.activity.mFinished && r.startsNotResumed) {

performPauseActivityIfNeeded(r, reason);

if (r.isPreHoneycomb()) {

r.state = oldState;

}

}

} else {

try {

//3

ActivityManagerNative.getDefault() .finishActivity(r.token, Activity.RESULT_CANCELED, null,

Activity.DONT_FINISH_TASK_WITH_ACTIVITY);

} catch (RemoteException ex) {

throw ex.rethrowFromSystemServer();

}

}

}

注释1处的performLaunchActivity方法用来启动Activity。

注释2处的代码用来执行Activity的onResume方法,将Activity的状态置为Resume。

注释3如果该Activity为null则会通知ActivityManager停止启动Activity。

ActivityThread#performLaunchActivity()

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

...

ActivityInfo aInfo = r.activityInfo; //1

if (r.packageInfo == null) {

r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,Context.CONTEXT_INCLUDE_CODE); //2

}

ComponentName component = r.intent.getComponent(); //3

...

Activity activity = null;

try {

java.lang.ClassLoader cl = r.packageInfo.getClassLoader();

activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent); //4

...

}

} catch (Exception e) {

...

}

try {

Application app = r.packageInfo.makeApplication(false, mInstrumentation); //5

...

if (activity != null) {

Context appContext = createBaseContextForActivity(r, activity); //6

...

}

//7

activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor, window);

...

if (r.isPersistable()) {

mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); //8

} else {

mInstrumentation.callActivityOnCreate(activity, r.state);
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

文末

不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊

小编将自己6年以来的面试经验和学习笔记都整理成了一个**937页的PDF,**以及我学习进阶过程中看过的一些优质视频教程。

其实看到身边很多朋友抱怨自己的工资很低,包括笔者也是一样的,其原因是在面试过程中没有给面试官一个很好的答案。所以笔者会持续更新面试过程中遇到的问题,也希望大家和笔者一起进步,一起学习。

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

**

文末

不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊

小编将自己6年以来的面试经验和学习笔记都整理成了一个**937页的PDF,**以及我学习进阶过程中看过的一些优质视频教程。

[外链图片转存中...(img-peIuUFcp-1712273114227)]

其实看到身边很多朋友抱怨自己的工资很低,包括笔者也是一样的,其原因是在面试过程中没有给面试官一个很好的答案。所以笔者会持续更新面试过程中遇到的问题,也希望大家和笔者一起进步,一起学习。

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
相关推荐
陌小呆^O^2 分钟前
Cmakelist.txt之win-c-udp-server
c语言·开发语言·udp
Gu Gu Study8 分钟前
枚举与lambda表达式,枚举实现单例模式为什么是安全的,lambda表达式与函数式接口的小九九~
java·开发语言
时光の尘23 分钟前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
-一杯为品-32 分钟前
【51单片机】程序实验5&6.独立按键-矩阵按键
c语言·笔记·学习·51单片机·硬件工程
以后不吃煲仔饭37 分钟前
Java基础夯实——2.7 线程上下文切换
java·开发语言
进阶的架构师38 分钟前
2024年Java面试题及答案整理(1000+面试题附答案解析)
java·开发语言
前端拾光者42 分钟前
利用D3.js实现数据可视化的简单示例
开发语言·javascript·信息可视化
程序猿阿伟43 分钟前
《C++ 实现区块链:区块时间戳的存储与验证机制解析》
开发语言·c++·区块链
傻啦嘿哟1 小时前
如何使用 Python 开发一个简单的文本数据转换为 Excel 工具
开发语言·python·excel
大数据编程之光1 小时前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink