文档章节

读Android源码-冷启动时的ActivityThread

天王盖地虎626
 天王盖地虎626
发布于 06/20 17:23
字数 718
阅读 5
收藏 0

 

冷启动创建应用时,ActivityThread的主要方法:

  1. main()
    -- 1. 开启消息循环
    -- 2. 通知ActivityManagerService
    -- 3. 添加GCWatcher
  2. handleBindApplication()
    -- 1. 创建LoadedApk
    -- 2. 创建Instrumentation
    -- 3. 创建Application
    -- 4. 通过Instrumentation调用Application的onCreate()方法

main()

main方法是一个应用创建的入口,他主要做了3件事

1. 开启消息循环

调用Looper.prepareLoop() Looper.loop(),开启主线程的消息循环,以便于ApplicationThread调用ActivityThread中的生命周期方法。

public static void main(String[] args) {
    ...
    Looper.prepareMainLooper();

    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
    ...
    Looper.loop();
}

2. 通知ActivityManagerService

调用ActivityThread.attach()方法,attach()方法在调用了attachApplication()将ApplicationThread这个Binder交给了ActivityManagerService,意味着ActivityManagerService可以通过ApplicationThread控制我们的应用,建立了服务器端对客户端的通信渠道。

private void attach(boolean system){
    ...
    final IActivityManager mgr = ActivityManager.getService();
    try {
        mgr.attachApplication(mAppThread);
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
    ...
}

SDK26以后,去除了Native和Proxy,而是直接从ActivityManager(ServiceManager)中获取ActivityManagerService的Binder对象进行通信

3. 添加GCWatcher

在attach()方法中,添加了监听dialvik内存使用情况得监听者GcWatcher,当内存使用超过总容量的3/4,则打印Log进行记录,并且调用ActivityManagerService的releaseSomeActivities()进行内存释放操作,以防止内存溢出导致应用崩溃。

private void attach(boolean system){
    ...
    BinderInternal.addGcWatcher(new Runnable() {
        @Override public void run() {
            if (!mSomeActivitiesChanged) {
                return;
            }
            Runtime runtime = Runtime.getRuntime();
            long dalvikMax = runtime.maxMemory();
            long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
            if (dalvikUsed > ((3*dalvikMax)/4)) {
                if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                        + " total=" + (runtime.totalMemory()/1024)
                        + " used=" + (dalvikUsed/1024));
                mSomeActivitiesChanged = false;
                try {
                    mgr.releaseSomeActivities(mAppThread);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            }
        }
    });
    ...
}

handleBindApplication()

ActivityManagerService=AMS
handleBindApplication的被调用时机是:

  1. 通过上面AMS.attachApplication()后,AMS获得了控制应用的Binder对象ApplicationThread。
  2. AMS进行了一系列操作后(这里先省略),调用了ApplicationThread的bindApplication()
  3. bindApplication中通过消息机制,sendMessage到ActivityThread,调用了ActivityThread的handleBindApplication()

handleBindApplication是创建用于所需组件的入口,他主要做了4件事:

1. 创建LoadedApk

LoadedApk对象包含应用的所有信息

private void handleBindApplication(AppBindData data){
    ...
    final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                    appContext.getClassLoader(), false, true, false);
    ...
}

2. 创建Instrumentation

Instrumentation是应用组件的管家,组件的生命周期方法都需要通过它来调用,是客户端与服务器端通信的最后一步。

private void handleBindApplication(AppBindData data){
    ...
    final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
    try {
        final ClassLoader cl = instrContext.getClassLoader();
        mInstrumentation = (Instrumentation)
            cl.loadClass(data.instrumentationName.getClassName()).newInstance();
    } catch (Exception e) {
        throw new RuntimeException(
            "Unable to instantiate instrumentation "
            + data.instrumentationName + ": " + e.toString(), e);
    }
    ...
}

3. 创建Application

调用了LoadedApk.makeApplication()进行Application的创建

private void handleBindApplication(AppBindData data){
    ...
    app = data.info.makeApplication(data.restrictedBackupMode, null);
    ...
}
  • 先通过ContextImpl.createAppContext()获得Application的Context
  • 再通过Instrumentation.newApplication(),用ClassLoder创建Applicaition
  • 创建后Applicaition调用自身的attach(Context)方法,将Context与Applicaition绑定,完成创建
LoadedApk.class
public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
    ...
    Application app = null;
    ...
    ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
    app = mActivityThread.mInstrumentation.newApplication(
            cl, appClass, appContext);
    ...
    return app;
}

4. 通过Instrumentation调用Application的onCreate()方法

private void handleBindApplication(AppBindData data){
    ...
    mInstrumentation.callApplicationOnCreate(app);
    ...
}

 

本文转载自:https://www.jianshu.com/p/5f3960becc3a

天王盖地虎626

天王盖地虎626

粉丝 28
博文 487
码字总数 20672
作品 0
南京
私信 提问
Android Activity启动流程(基于Android8.0系统)

主要对象介绍 ActivityManagerService:负责系统中所有Activity的生命周期; ActivityThread:App的真正入口,当App启动后,会调用其main方法开始执行,开启消息循环队列。是传说中的UI线程,...

天王盖地虎626
06/11
0
0
(Android 9.0)Activity启动流程源码分析

前言 熟悉Activity的启动流程和运行原理是一个合格的应用开发人员所应该具备的基本素质,其重要程度就不多做描述了。同时,知识栈应该不断的更新,最新发布的Android 9.0版本相较于之前的几个...

天王盖地虎626
06/21
0
0
ActivityThread的理解和APP的启动过程

ActivityThread的理解和APP的启动过程 ActivityThread ActivityThread的初始化 主线程Looper的初始化 主线程Handler的初始化 ApplicationThread及Activity的创建和启动 APP的启动 系统的启动...

天王盖地虎626
06/20
0
0
深入理解Android-Activity的启动过程

一、准备工作 1、准备好阅读源码的工具。 2、主要类的功能介绍 ActivityManagerServices 简称AMS,服务端对象,是Android中最核心的服务,主要负责系统中四大组件的启动、切换和调度及应用进...

天王盖地虎626
06/20
0
0
探索Activity启动流程-实现打开插件中的Activity

通过分析Activity的启动流程,探索Android的插件化,下面通过源码分析实现一个简单的插件化 打开一个 未安装apk中的Activity 开始分析 Activity的启动流程从 startActivity开始 然后通过 In...

liwg
2018/05/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

日期时间命令date

命令date 用途:打印或设置系统日期和时间 语法:date [选项]... [+格式] 选项: -s, --set=STRING 根据 STRING 设置时间 -u, --utc, --universal 显示或设置全球时...

迷失De挣扎
32分钟前
0
0
小白讲网络安全系列

注入攻击防护 XSS注入 SQL注入 命令注入 文件上传 文件解压缩 CSRF防护 对称加密 非对称加密 数字证书 数字签名 完整性校验 消息验证码 单向散列Hash函数 口令单向加密算法 审计日志 认证鉴权...

一刀
今天
2
0
MYSQL 嵌套事务(SAVEPOINT) 与Spring 事务传播

摘要 savepoint 关键字可以实现嵌套事务。结合savepoint关键字,更方便理解spring的事务传播。 事务嵌套 初始化表脚本 drop table t;create table t(a int, primary key(a)); 开启事务 my...

liangxiao
今天
3
0
Chrome OS 更新新版本可让Linux访问USB连接的Android设备

谷歌再次为Chrome OS带来了重大版本更新,使版本号达到了75。本次更新的一大亮点就是允许在Chrome OS上运行的Linux能够识别通过USB方式连接的Android设备,能够让用户使用Linux进行调试等等。...

linuxCool
昨天
15
0
聊聊feign的HystrixInvocationHandler

序 本文主要研究一下feign的HystrixInvocationHandler HystrixInvocationHandler feign-hystrix-10.2.3-sources.jar!/feign/hystrix/HystrixInvocationHandler.java final class HystrixInvo......

go4it
昨天
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部