Activity启动过程(一)AMS
在前面《Android启动过程》中提到了System进程启动ActivityManagerService服务,AMS是由Android提供的用于管理Activity(不仅仅指Activity,还包括其他三个组件)运行状态的系统进程,则是平时编写APK应用程序时使用得最频繁的一个系统服务。
/** @path: \frameworks\base\services\java\com\android\server\SystemServer.java */
class ServerThread extends Thread {@Overridepublic void run() {...... // Critical services...boolean onlyCore = false;try {// 创建Activity Manager实例context = ActivityManagerService.main(factoryTest);.....// 将AMS注册到ServiceManager中(前面分析提到这一步是在创建PMS实例之后才进行注册)ActivityManagerService.setSystemProcess();} catch (RuntimeException e) {}}
}
2、如前所述,其是通过调用ActivityManagerService#main函数来创建AMS实例及AMS线程:
/** @path \frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java<span style="font-family: Arial, Helvetica, sans-serif;"> **/ </span>
public final class ActivityManagerService extends ActivityManagerNativeimplements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {static ActivityManagerService mSelf; public static final Context main(int factoryTest) {/** 创建一个AThread线程 ,这里用来创建AMS实例*/AThread thr = new AThread();thr.start(); // 启动AMS线程synchronized (thr) {/** 这里运来判断AMS是否启动成功,失败则一直等待 **/while (thr.mService == null) {try {// 注意这里会wait,直至AThread中AMS创建完成,调用notiyAll方法才唤醒thr.wait();} catch (InterruptedException e) {}}}// 将AThread中创建的AMS实例赋值给m,再赋值给AMS静态变量mSelfActivityManagerService m = thr.mService;mSelf = m;/** AMS两个最重要核心——* - ActivityStack:Activity的记录者与管理者,同时也为AMS管理系统运行情况提供了基础* - ActivityTask**/ActivityThread at = ActivityThread.systemMain();mSystemThread = at;Context context = at.getSystemContext();context.setTheme(android.R.style.Theme_Holo);m.mContext = context;m.mFactoryTest = factoryTest;/** 创建一个ActivityStack对象 **/m.mMainStack = new ActivityStack(m, context, true); m.mBatteryStatsService.publish(context);m.mUsageStatsService.publish(context);synchronized (thr) {thr.mReady = true;// 唤醒AMS线程thr.notifyAll();}/*** 开始运行 ***/m.startRunning(null, null, null, null);return context;}static class AThread extends Thread {ActivityManagerService mService;boolean mReady = false;public AThread() {super("ActivityManager");}public void run() {/** 创建消息Loopr循环 **/Looper.prepare();android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);android.os.Process.setCanSelfBackground(false);/** 在这里创建AMS实例,用以作为系统中的Activity管理服务 **/ActivityManagerService m = new ActivityManagerService();synchronized (this) {mService = m;// 这里唤醒前面等待的线程notifyAll();}synchronized (this) {while (!mReady) {try {// 创建完成后wait等待,直至System线程将其唤醒wait();} catch (InterruptedException e) {}}}Looper.loop();}}
}
3、通过ActivityManagerService#setSystemProcess将AMS注册到ServiceManager中:
/** @path \frameworks\base\services\java\com\android\server\am\ActivityManagerService.java **/
public static void setSystemProcess() {try {// mSelf是静态变量,即前面启动的AMS实例ActivityManagerService m = mSelf;/** 这里通过ServiceManager来注册各种服务,其中AMS服务的主体是第一个即"activity" **/ServiceManager.addService("activity", m, true);ServiceManager.addService("meminfo", new MemBinder(m));ServiceManager.addService("gfxinfo", new GraphicsBinder(m));ServiceManager.addService("dbinfo", new DbBinder(m));if (MONITOR_CPU_USAGE) {ServiceManager.addService("cpuinfo", new CpuBinder(m));}ServiceManager.addService("permission", new PermissionController(m));ApplicationInfo info =mSelf.mContext.getPackageManager().getApplicationInfo("android", STOCK_PM_FLAGS);mSystemThread.installSystemApplicationInfo(info);synchronized (mSelf) {ProcessRecord app = mSelf.newProcessRecordLocked(mSystemThread.getApplicationThread(), info,info.processName, false);app.persistent = true;app.pid = MY_PID;app.maxAdj = ProcessList.SYSTEM_ADJ;mSelf.mProcessNames.put(app.processName, app.uid, app);synchronized (mSelf.mPidsSelfLocked) {mSelf.mPidsSelfLocked.put(app.pid, app);}mSelf.updateLruProcessLocked(app, true);}} catch (PackageManager.NameNotFoundException e) {}
}
<activityandroid:name="com.loadingUI.LoadingActivity"android:label="@string/Loadinging_activity"><intent-filter><action android:name="android.intent.action.MAIN"/><category android:name="android.intent.category.LAUNCHER"/></intent-filter>
</activity>
Launcher组件在启动时,会向PackageManagerService查询系统中所有“action”等于"action.MAIN"以及"category"等于"category.LAUNCHER"的Activity组件,为每一个Activity组件创建一个快捷图标。
public final class Launcher extends Activityimplements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks, View.OnTouchListener
1.2)点击响应函数Launcher#onClick:
/** \packages\apps\Launcher2\src\com\android\launcher2*/
public void onClick(View v) {...Object tag = v.getTag();if (tag instanceof ShortcutInfo) {// 这里组装启动intent的信息final Intent intent = ((ShortcutInfo) tag).intent;int[] pos = new int[2];v.getLocationOnScreen(pos);intent.setSourceBounds(new Rect(pos[0], pos[1],pos[0] + v.getWidth(), pos[1] + v.getHeight()));/** 看到通过这个函数用来启动一个应用的根Activity*/boolean success = startActivitySafely(v, intent, tag);if (success && v instanceof BubbleTextView) {mWaitingForResume = (BubbleTextView) v;mWaitingForResume.setStayPressed(true);}} .......
}
可以看到Launcher通过函数startActivitySafely来启动应用程序的根Activity;
1.2)Launcher#startActivitySafely方法:
/** \packages\apps\Launcher2\src\com\android\launcher2*/
boolean startActivitySafely(View v, Intent intent, Object tag) {boolean success = false;try {/** 函数很简单,只是对startActivity进行了安全封装*/success = startActivity(v, intent, tag);} catch (ActivityNotFoundException e) {...}return success;
}
可以看到startActivitySafely仅仅是对startActivity方法做了一个try-catch安全封装,用以安全启动,最终目的仍是调用startActivity来启动根Activity。
1.3)Launcher#startActivity函数:
boolean startActivity(View v, Intent intent, Object tag) {/*** 设置启动标志***/intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);try {// Only launch using the new animation if the shortcut has not opted out (this is a// private contract between launcher and may be ignored in the future).boolean useLaunchAnimation = (v != null) &&!intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);UserHandle user = (UserHandle) intent.getParcelableExtra(ApplicationInfo.EXTRA_PROFILE);LauncherApps launcherApps = (LauncherApps)this.getSystemService(Context.LAUNCHER_APPS_SERVICE);// 当添加新的启动动画时,使用此启动方式if (useLaunchAnimation) {ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,v.getMeasuredWidth(), v.getMeasuredHeight());if (user == null || user.equals(android.os.Process.myUserHandle())) {/** 注意这里将会调用父类的startActivity*/startActivity(intent, opts.toBundle());} else {launcherApps.startMainActivity(intent.getComponent(), user,intent.getSourceBounds(), opts.toBundle());}} else { // 默认的启动方式if (user == null || user.equals(android.os.Process.myUserHandle())) {/** 调用父类Activity的startActivity来启动 **/startActivity(intent);} else {launcherApps.startMainActivity(intent.getComponent(), user,intent.getSourceBounds(), null);}}return true;} catch (SecurityException e) {...}return false;
}
上面代码重要完成两个工作:
public class Activity extends ContextThemeWrapperimplements LayoutInflater.Factory2,Window.Callback, KeyEvent.Callback,OnCreateContextMenuListener, ComponentCallbacks2,Window.OnWindowDismissedCallback
/** \frameworks\base\core\java\android\app\Activity.java*/
@Override
public void startActivity(Intent intent) {this.startActivity(intent, null);
}@Override
public void startActivity(Intent intent, @Nullable Bundle options) {if (options != null) {startActivityForResult(intent, -1, options);} else {// Note we want to go through this call for compatibility with// applications that may have overridden the method.startActivityForResult(intent, -1);}
}
最终将会调用startActivityForResult来执行函数,第二个参数设为-1表示不需要知道最终的执行结果。
2、来分析Activity#startActivityForResult方法:
public void startActivityForResult(Intent intent, int requestCode) {startActivityForResult(intent, requestCode, null);
}public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {/** mParent在调用attach函数时传入*/if (mParent == null) {/** Instrumentation类用以监控应用程序与系统之间的交互,* 这里通过其execStartActivity来启动Activity组件**/Instrumentation.ActivityResult ar =mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);if (ar != null) {mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData());}/** 这个本情况下不需要*/if (requestCode >= 0) {mStartedActivity = true;}/** 有关界面加载SurfaceFlinger*/final View decor = mWindow != null ? mWindow.peekDecorView() : null;if (decor != null) {decor.cancelPendingInputEvents();}} else {...}if (options != null && !isTopOfTask()) {mActivityTransitionState.startExitOutTransition(this, options);}
}
注意execStartActivity中的传参param:
private IBinder mToken;
mToken是一个Binder代理对象,指向了ActivityManagerService中一个类型为ActivityRecord的Binder本地对象。每一个已经启动的Activity组件在AMS(ActivityManagerService)中都存在一个对应的ActivityRecord对象,用来维护对应的Activity组件的运行状态及信息。
Instrumentation是执行application instrumentation代码的基类。当应用程序运行的时候instrumentation处于开启,Instrumentation将在任何应用程序运行前初始化,可以通过它监测系统与应用程序之间的交互。Instrumentation implementation通过的AndroidManifest.xml中的<instrumentation>标签进行描述。
Instrumentation似乎有些类似与window中的“钩子(Hook)函数”,在系统与应用程序之间安装了个“窃听器”。
1、Instrumentation#execStartActivity函数:
Instrumentation.ActivityResult ar =mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
函数源码:
/** \frameworks\base\core\java\android\app\Instrumentation.java*/
public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {IApplicationThread whoThread = (IApplicationThread) contextThread;/** mActivityMonitors定义:List<ActivityMonitor> mActivityMonitors;* ActivityMoniter:有关特定的Intent的监视。* 一个ActivityMoniter类的实例通过函数addMonitor* (Instrumentation.ActivityMonitor)添加到当前* instrumentation中,一旦添加后,每当启动一个新的Activity,* ActivityMoniter就会检测,如果匹配,其hit count计数更新* 等其他操作。一个ActivityMonitor也可以用来寻找一个Activity,* 通过waitForActivity()方法,这个函数将返直到匹配的活动被创建。*/// 这里与主线无关,可以不用关心if (mActivityMonitors != null) {synchronized (mSync) {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();// 主要的执行函数在这里,调用了ActivityManagerNative中的startActivityint 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) {}return null;
}
上述代码中最重要的作用是调用了ActivityManagerNative.getDefault().startActivity方法;getDefault用以获取AMS的一个代理对象ActivityManagerNative,接着再调用它的成员函数startActivity来通知AMS将有一个Activity组件启动。
/** \frameworks\base\core\java\android\app\ActivityManagerNative.java*/public abstract class ActivityManagerNative extends Binder implements IActivityManager
1、ActivityManagerNative#getDefault函数:
/** \frameworks\base\core\java\android\app\ActivityManagerNative.java*/static public IActivityManager getDefault() {// 单例类Singleton中的函数,get是Singleton类中的方法,见下面附Ireturn gDefault.get();}// Singleton为单例模式的实现,是个抽象类,见附一private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {protected IActivityManager create() {// 前面AMS分析中提到的AMS的主要服务"activity",通过SM获取IBinder b = ServiceManager.getService("activity");...IActivityManager am = asInterface(b);...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(),返回一个IActivityManager类;
附I、Singleton类
/*** Singleton helper class for lazily initialization.* Modeled after frameworks/base/include/utils/Singleton.h*/public abstract class Singleton<T> {private T mInstance;protected abstract T create();public final T get() {synchronized (this) {if (mInstance == null) {mInstance = create();}return mInstance;}}}
可以看到gDefault的定义是Singleton<IActivityManager>,调用get函数则是返回IActivityManager的具体实例对象。
在定义gDefault时,需要重写abstract函数create();在create函数中,可以看到它通过ServiceManager获取到一个服务名为"activity"的服务代理对象即一个引用了ActivtyManagerService的代理对象。
回到前面的步骤可知,ActivityManagerNative.getDefault().startActivity方法最终调用的是ActivityManagerProxy.startActivity方法。
/** \frameworks\base\core\java\android\app\ActivityManagerNative.java*/
class ActivityManagerProxy implements IActivityManager {public ActivityManagerProxy(IBinder remote) {mRemote = remote;}public IBinder asBinder() {return mRemote;}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 {/*** 写入启动Activity的信息到Parcel对象data中 **/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);}/** 通过Binder进行进程间通信,通过mRemote来向AMS发送START_ACTIVITY_TRANSACTION类型* 的进程间请求 **/mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);reply.readException();int result = reply.readInt();reply.recycle();data.recycle();return result;}
}
和通常的Binder通信机制相同,这里使用ActivityManagerProxy将Activity组件的信息封装到一个Parcel对象中,通过Binder机制传递给AMS,发起进程间通信请求。接下来的启动操作则会在AMS中进行。
Activity启动过程(一)AMS相关推荐
- activity启动流程_以AMS视角看Activity启动过程
原文作者:Levi_wayne 原文地址:blog.csdn.net/u012551754/article/details/78822782 特别声明:本文转载自网络,版权归作者所有,如有侵权请联系删 ...
- activity 生命周期_死磕Android_App 启动过程(含 Activity 启动过程)
1. 前言 Activity是日常开发中最常用的组件,系统给我们做了很多很多的封装,让我们平时用起来特别简单,很顺畅.但是你有没有想过,系统内部是如何启动一个Activity的呢?Activity对象 ...
- 【Android 插件化】Hook 插件化框架 ( 从 Hook 应用角度分析 Activity 启动流程 二 | AMS 进程相关源码 | 主进程相关源码 )
Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...
- Android系统(117)---Activity启动过程
Activity启动过程 ###一些基本的概念 ActivityManagerServices,简称AMS,服务端对象,负责系统中所有Activity的生命周期 ActivityThread,App的 ...
- Android深入四大组件(五)Android8.0 根Activity启动过程(后篇)
前言 在几个月前我写了Android深入四大组件(一)应用程序启动过程(前篇)和Android深入四大组件(一)应用程序启动过程(后篇)这两篇文章,它们都是基于Android 7.0,当我开始阅读An ...
- 死磕Android_App 启动过程(含 Activity 启动过程)
1. 前言 Activity是日常开发中最常用的组件,系统给我们做了很多很多的封装,让我们平时用起来特别简单,很顺畅.但是你有没有想过,系统内部是如何启动一个Activity的呢?Activity对象 ...
- Activity启动过程详解(Android P)
本章我们来分析Activity的启动过程. 我们知道,Activity可以通过两种方式启动:一种是点击应用程序图标,Launcher会启动主Activity:另一种是在应用程序内部,调用startAc ...
- Android 面试必备 - 系统、App、Activity 启动过程
前言 最近准备更新 Android 面试必备基础知识系列,有兴趣的可以关注我的微信公众号 stormjun94,有更新时,第一时间会在微信公众号上面发布,同时,也会同步在 GitHub 上面更新,如果 ...
- Android深入四大组件(六)Android8.0 根Activity启动过程(前篇)
相关文章 Android深入四大组件系列 Android系统启动系列 Android应用程序进程系列 Android深入解析AMS系列 前言 在几个月前我写了Android深入四大组件(一)应用程序启 ...
- Android深入四大组件(七)Android8.0 根Activity启动过程(后篇)
相关文章 Android深入四大组件系列 Android系统启动系列 Android应用程序进程系列 Android深入解析AMS系列 前言 在几个月前我写了Android深入四大组件(一)应用程序启 ...
最新文章
- 记一次mpvue开发完整小程序相关笔记
- 卡地亚搜索引擎_「AF厂卡地亚猎豹」网站SEO优化新方向
- android 自定义模板下载,android studio 自定义模板
- linux 线程退出 signal,Linux signal 那些事儿 (3)
- WPF开发的实用小工具 - 快捷悬浮菜单
- 时尚排毒法可用性到底多大? - 生活至上,美容至尚!
- 【万字干货】OpenMetric与时序数据库存储模型分析
- 算法训练 字符串编辑(java)
- centos6.8安装telnet
- OSChina 周一乱弹 —— 最无法理解的程序员行为
- windows下python访问ipv6报错
- 从0开始,设计研发一个全功能通用大数据系统
- 软考高级《信息系统项目管理师》(简称高项)考证经验(满满的干货)
- matlab 卷积改变步长,转载“MATLAB卷积函数改进”
- 对路径“C:\Program Files (x86)\gwssi\CPC客户端\CheckWord.xml”的访问被拒绝。
- 入门物联网需要服务器
- 微信公众号开发者模式入门
- 开篇:内容提要 (《蓝调口琴指南》名作拙译)
- 【CF802O】April Fools‘ Problem (hard)(wqs二分,模拟费用流,老鼠进洞)
- 信息与计算机科学讲座,【创新创业 计科在行动】2015级信息与计算科学专业大学生创新讲座、专业教育讲座暨学术前沿讲座专题报道...
热门文章
- django+layui表格数据管理
- c51单片机矩阵键盘1602计算器_基于AT89C51单片机的十进制计算器系统设计
- cad填充密度怎么调整_CAD填充比例调好了,填充物数量怎么调,就是密度怎么调?...
- 互联网金融网络借贷系统架构
- daemontools安装和使用
- p6spy mysql8_P6Spy配置使用
- 计算机日期函数公式大全,Excel技巧: 根据日期汇总月份的计算公式
- 免费好用的内网穿透 端口映射工具 实现一键远程 外网访问内网
- Java、JSP网上音像管理系统的设计与实现
- C#读写西门子PLC数据