Android Framework学习笔记(五)应用程序启动过程,安卓开发项目经历

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的时序图:

image

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

}

if (!r.activity.mFinished) {

activity.performStart(); //9

r.stopped = false;

}

mActivities.put(r.token, r); //10

}

return activity;

}

注释1处用来获取ActivityInfo。

注释2处获取APK文件的描述类LoadedApk。

注释3处获取要启动的Activity的ComponentName类,ComponentName类中保存了该Activity的包名和类名。

注释4处根据ComponentName中存储的Activity类名,用类加载器通过反射来创建该Activity的实例。

注释5处用来创建Application对象,makeApplication方法内部会调用Application的onCreate方法。该Application对象的唯一作用就是作为参数传递到Activity里,然后在Activity类中可以获得调用getApplication方法来获取Application对象。

注释6处用来创建要启动Activity的上下文环境ContextImpl。

注释7处调用Activity的attach方法初始化Activity,将ContextImpl对象注册到对应的Activity中,之后在Activity类中就可以使用Context的所有功能了。

注释8处会调用Instrumentation的callActivityOnCreate方法来启动Activity。

注释9处用来执行Activity的onStart方法。

注释10处将启动的Activity加入到ActivityThread的成员变量mActivities中,其中mServices是ArrayMap类型。

先来看看注释5方法:

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

LoadedApk#makeApplication()

public Application makeApplication(boolean forceDefaultAppClass,

Instrumentation instrumentation) {

if (mApplication != null) { //1

return mApplication;

}

Application app = null;

try {

ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);

app = mActivityThread.mInstrumentation.newApplication(

cl, appClass, appContext); //2

} catch (Exception e) {

}

if (instrumentation != null) {

try {

instrumentation.callApplicationOnCreate(app); //3

} catch (Exception e) {

}

}

}

return app;

}

注释1判断当前应用是否是第一次创建Application对象,如果不是则直接返回Application对象,否则执行注释2创建第一个Application对象。目的是确保当前应用之创建了一个全局的Application对象。

注释2调用Instrumentation的newApplication()方法创建Application。

注释3调用Instrumentation的callApplicationOnCreate()。

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

Instrumentation#newApplication()

public Application newApplication(ClassLoader cl, String className, Context context)

throws InstantiationException, IllegalAccessException,

ClassNotFoundException {

return newApplication(cl.loadClass(className), context);

}

static public Application newApplication(Class<?> clazz, Context context)

throws InstantiationException, IllegalAccessException,

ClassNotFoundException {

Application app = (Application)clazz.newInstance(); //1

app.attach(context); //2

return app;

}

注释1简单粗暴,通过反射创建一个Application实例。

注释2处调用Application的attach方法初始化Application,将ContextImpl对象注册到对应的Application中,之后在Application类中就可以使用Context的所有功能了。

Instrumentation#callApplicationOnCreate()

public void callApplicationOnCreate(Application app) {

app.onCreate();

}

这样Application的onCreate()方法也得到执行。

现在已经有了Application且它的onCreate()方法也得到执行。但Activity只是被ClassLoader装载了,onCreate()还没有调起来。回到ActivityThread的performLaunchActivity()方法,看看注释8的方法:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

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

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

img

img

img

img

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

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

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

最后

感觉现在好多人都在说什么安卓快凉了,工作越来越难找了。又是说什么程序员中年危机啥的,为啥我这年近30的老农根本没有这种感觉,反倒觉得那些贩卖焦虑的都是瞎j8扯谈。当然,职业危机意识确实是要有的,但根本没到那种草木皆兵的地步好吗?

Android凉了都是弱者的借口和说辞。虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

所以,最后这里放上我耗时两个月,将自己8年Android开发的知识笔记整理成的Android开发者必知必会系统学习资料笔记,上述知识点在笔记中都有详细的解读,里面还包含了腾讯、字节跳动、阿里、百度2019-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。

以上全套学习笔记面试宝典,吃透一半保你可以吊打面试官,只有自己真正强大了,有核心竞争力,你才有拒绝offer的权力,所以,奋斗吧!骚年们!千里之行,始于足下。种下一颗树最好的时间是十年前,其次,就是现在。

最后,赠与大家一句诗,共勉!

不驰于空想,不骛于虚声。不忘初心,方得始终。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

1712336833208)]

[外链图片转存中…(img-Hy1dp550-1712336833209)]

[外链图片转存中…(img-1tbKBOpk-1712336833209)]

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

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

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

最后

感觉现在好多人都在说什么安卓快凉了,工作越来越难找了。又是说什么程序员中年危机啥的,为啥我这年近30的老农根本没有这种感觉,反倒觉得那些贩卖焦虑的都是瞎j8扯谈。当然,职业危机意识确实是要有的,但根本没到那种草木皆兵的地步好吗?

Android凉了都是弱者的借口和说辞。虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

所以,最后这里放上我耗时两个月,将自己8年Android开发的知识笔记整理成的Android开发者必知必会系统学习资料笔记,上述知识点在笔记中都有详细的解读,里面还包含了腾讯、字节跳动、阿里、百度2019-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。

[外链图片转存中…(img-x7Z9Fwf2-1712336833209)]

以上全套学习笔记面试宝典,吃透一半保你可以吊打面试官,只有自己真正强大了,有核心竞争力,你才有拒绝offer的权力,所以,奋斗吧!骚年们!千里之行,始于足下。种下一颗树最好的时间是十年前,其次,就是现在。

最后,赠与大家一句诗,共勉!

不驰于空想,不骛于虚声。不忘初心,方得始终。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值