【Android 启动过程】Activity 启动源码分析 ( ActivityThread 流程分析 一 )
文章目录
- 一、ActivityThread 主函数启动
- 二、ActivityThread 绑定 ApplicationThread
- 三、AMS attachApplication -> attachApplicationLocked 绑定 ApplicationThread
- 四、ApplicationThread.bindApplication 绑定 ApplicationThread
- 五、ActivityThread.H 处理 BIND_APPLICATION 消息
- 六、ActivityThread.handleBindApplication 处理绑定问题
- 七、LoadedApk.makeApplication 创建 Application 对象
- 八、Instrumentation.newApplication 创建 Application 对象
- 九、AppComponentFactory.instantiateApplicationCompat 创建 Application 对象
一、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.info
是 LoadedApk
类型 ;
/**
* 管理应用程序进程中主线程的执行、调度和执行活动、广播以及活动管理器请求的其他操作。
*
* {@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 对象
调用 LoadedApk
的 makeApplication
方法 , 创建 Application
实例 , 在该方法中通过调用 Instrumentation
的 newApplication
方法 , 创建 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 对象
在 LoadedApk
的 makeApplication
方法 中 , 调用了 Instrumentation
的 newApplication
方法创建 Application
实例对象 ;
/**
* 用于实现应用程序检测代码的基类。
* 当在启用检测的情况下运行时,该类将在任何应用程序代码之前为您实例化,
* 从而允许您监视系统与应用程序之间的所有交互。
* 通过AndroidManifest.xml的&lt;仪器仪表&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 对象
在 Instrumentation
的 newApplication
方法中 , 调用了 AppComponentFactory
的 instantiateApplicationCompat
方法 , 创建 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 ;
相关文章
- Android取消RecyclerView、ListView、ScrollView、HorizontalScrollView滑动到边缘闪现灰白色水波纹动画
- android学习一(了解android)
- android初学问题集
- Android必知必会-App 常用图标尺寸规范汇总
- 从代码分析Android-Universal-Image-Loader的图片加载、显示流程
- Android 四大组件之一:BroadCastReceiver动态注册广播流程
- Android中RelativeLayout各个属性的含义
- 【已解决】Android Studio 加载自定义properties文件出错java.lang.ExceptionInInitializerError Caused by: java.lang.Nu
- 【Android】安卓闪电复习
- Android多功能视频播放器GSYVideoPlayer开发流程
- Maven 私服Nexus的搭建教程windows(搭配android maven插件使用)
- android应用程序分享,蓝牙文件传输(代码)
- Android开启手电筒功能(完美适配Android4x,5x,6x)
- Android 6.0 M的新特性
- Android之Fragment优点
- 世界级的Android测试开发流程(一)
- 【Android 应用开发】UI绘制流程 ( 生命周期机制 | 布局加载机制 | UI 绘制流程 | 布局测量 | 布局摆放 | 组件绘制 | 瀑布流布局案例 )
- 【Android 应用开发】Paint 滤镜 颜色矩阵 应用 ( 颜色矩阵使用流程 | 颜色通道值翻倍 | 颜色通道值增加 | 颜色反转 | 底片效果 | 黑白效果 | 复古效果 | 美颜效果 )
- 【Android 应用开发】Paint 渲染 之 BitmapShader 位图渲染 ( 渲染流程 | CLAMP 拉伸最后像素 | REPEAT 重复绘制图片 | MIRROR 绘制反向图片 )
- 【Android Gradle】安卓应用构建流程 ( Java 源码编译 和 AIDL 文件编译 )
- Android AudioManager控制系统声音的流程
- Android 富有动感的底部弹出框
- Android系统启动流程—— init进程zygote进程SystemServer进程启动流程
- 【Android 内存优化】Bitmap 长图加载 ( BitmapRegionDecoder 简介 | BitmapRegionDecoder 使用流程 | 区域解码加载示例 )
- Android 功耗(10)---电流波形图(power monitor)