文章目录
- 一、 应用入口函数 ActivityThread 主函数 main
- 二、 ActivityThread 类 attach 方法 ( 应用加载 )
- 三、 ActivityThread 类 handleBindApplication 方法 ( 应用创建 )
- 四、 启动优化项目
一、 应用入口函数 ActivityThread 主函数 main
1 . 执行应用主函数 : Launcher 应用与 Zygote 进程进行通信后 , 通知 Zygote 进程 fork 一个新的进程 , 该新进程中通过 System Server 执行 ActivityThread , 执行 ActivityThread 中的主函数 ;
2 . Android 应用主函数简介 : 安卓应用的 main 函数定义在 ActivityThread.java 中 , 该主函数被封装起来了 , Android 应用在编译之后 , 是需要被打包到 apk 安装文件中的 , 这是整个应用的入口函数 , 这个入口文件就是 ActivityThread.java 类 ;
- 安卓应用主函数 : Android 开发者开发安卓应用时 , 是不需要自己定义主函数的 , 由开发环境自动生成 ;
- 苹果应用主函数 : iOS 开发者开发苹果应用程序时 , 需要自己写主函数 ;
3 . Java 栈内操作 : 在 Java 栈区域 , 会实例化 Application , 调用 Application 的 onCreate 方法 , 然后开启主界面 Activity ; 这些操作都是在 ActivityThread 中完成的 ;
4 . 应用入口主函数部分代码示例 : 下面代码是 ActivityThread 部分代码 , 省略
万行代码 , 只展示下主函数 ;
代码语言:javascript复制public final class ActivityThread {
public static void main(String[] args) {
// 主函数中先初始化 Looper MessageQueue
// 将主线程转为 Looper 线程
// 这也是在 Activity 中可以直接定义 Handler 就可以使用的原因
Looper.prepareMainLooper();
// 这是主线程
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
}
}
该代码路径为 frameworksbasecorejavaandroidappActivityThread.java , 这是 Android 应用的入口主函数定义文件
二、 ActivityThread 类 attach 方法 ( 应用加载 )
1 . attach 方法引入 : 在上述 ActivityThread 类中的 main 函数中 , 创建 ActivityThread 对象 , 并调用了该对象的 attach 方法 , 下面开始分析该方法的源码 ;
代码语言:javascript复制 ActivityThread thread = new ActivityThread();
thread.attach(false);
在 attach 方法中 , 开启应用 , 加载 application 应用 , 然后加载 Activity 界面 ;
2 . 加载 Application 应用过程 :
① 获取进程引用 : 首先获取进程引用 IActivityManager mgr , 此处涉及进程通信 , IActivityManager 是进程的引用 , 可以与其它进程进行通信 ;
代码语言:javascript复制// ActivityThread.java
final IActivityManager mgr = ActivityManagerNative.getDefault();
② 绑定 Application 应用 : 调用 IActivityManager 对象的 attachApplication 方法 , 调用该方法后 , 通过跨进程通信方式回调 ActivityThread 中的 handleBindApplication 方法 , 这个操作是由系统回调的 , 主要操作是初始化应用 Application ;
代码语言:javascript复制// ActivityThread.java
mgr.attachApplication(mAppThread);
3 . ActivityThread.java 中的 attach 方法代码 : 展示部分代码细节 , 详细的类 , 去查看 ActivityThread.java 源码 ;
代码语言:javascript复制 // ActivityThread.java
private void attach(boolean system) {
// mgr 是进程 , 涉及到进程间通信 , IActivityManager 是进程的引用
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
// 绑定 Application 应用
// 调用该方法后 , 通过进程方式回调 ActivityThread 中的 handleBindApplication 方法
// 这个操作是由系统回调的
// 主要操作是初始化应用 Application
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
}
该代码路径为 frameworksbasecorejavaandroidappActivityThread.java , 这是 Android 应用的入口主函数定义文件
三、 ActivityThread 类 handleBindApplication 方法 ( 应用创建 )
handleBindApplication 处理 Application 应用绑定方法 , 这是创建 Application 应用核心过程 ;
1 . 方法调用者 : 该方法是由进程回调的 , 回调时传入的 AppBindData data 参数 , 包含了所有应用相关信息 , 如创建位置 , 包名 ;
代码语言:javascript复制// ActivityThread.java
private void handleBindApplication(AppBindData data) {
}
2 . 创建应用核心代码 : 从进程中传入的 AppBindData data 参数的 info 信息中获取 Application 应用 , 这是获取应用的核心方法 ;
( 此时该 Application 是一个空的应用 , 还没有执行 onCreate 方法 )
代码语言:javascript复制// ActivityThread.java
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
3 . 执行应用 Application 的 onCreate 方法 : 下面的代码会触发执行 Application 的 onCreate 方法 ;
代码语言:javascript复制// ActivityThread.java
mInstrumentation.callApplicationOnCreate(app);
4 . Instrumentation 的 callApplicationOnCreate 方法 : 很简单的调用方法 , 直接调用 Application 的 onCreate 方法 ;
代码语言:javascript复制 // Instrumentation.java
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
该代码所在文件路径为 frameworksbasecorejavaandroidappInstrumentation.java
5 . ActivityThread 类 handleBindApplication 方法部分源码参考 :
代码语言:javascript复制 // ActivityThread.java
private void handleBindApplication(AppBindData data) {
// ... 省略 1 万行代码
// Allow disk access during application and provider setup. This could
// block processing ordered broadcasts, but later processing would
// probably end up doing the same disk access.
// 允许磁盘在应用和 provider 创建时访问 .
// 该操作可能阻塞处理有序广播 , 但是稍后处理会完毕后 , 会允许同样的磁盘访问 ;
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
try {
// If the app is being launched for full backup or restore, bring it up in
// a restricted environment with the base application class.
// 进程中传入的 AppBindData data 参数 , 包含了 Application 应用
// 这是创建 Application 的过程
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
try {
// 执行 Application 的 onCreate 方法
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " app.getClass().getName()
": " e.toString(), e);
}
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
该代码路径为 frameworksbasecorejavaandroidappActivityThread.java , 这是 Android 应用的入口主函数定义文件
四、 启动优化项目
在 Launcher 应用点击图标后 , 启动应用 , 系统为应用开启进程 , 分配内存的步骤是无法干预的 , 开发者能做启动优化的地方只有两个位置 , 一个是 Application 的 onCreate 方法 , 另一个是 Activity 的 onCreate 方法 ;
1 . Application 的 onCreate 方法 : 在应用的 Application 创建时 , 需要调用 Application 中的 onCreate 方法 , 这里面绝对不能有耗时操作 , 直接影响到 ActivityThread 中初始化 Application 步骤的消耗时间 ;
2 . Activity 的 onCreate 方法 : 一般在 Activity 界面中 , 需要加载 xml 布局文件 , 显示布局文件中的画面 ;