Android 中你碰不到但是很重要的类之ActivityThread

news2024/11/27 15:43:33

作者:Drummor

通过本文能了解一下内容

1、和系统进程打交道的桥头堡

应用进程起来之后ART(Android Runtime)第一站就是ActivityThread,代码层面上就是ActivityThread的main()方法,是不是很熟悉,爷青回啊,这不就是java的main方法嘛

   public static void main(String[] args) {
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);
        sMainThreadHandler = thread.getHandler();
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

该方法是一个静态方法,里面做了重要的两件事

  • 创建了让主线程Looper开始工作,并创建了一个Handler
  • 给system_server【递纸条】告诉他联系方式,告诉sytem_servr进程与应用进程取得联系可以通过ApplicationThread这个binder。看下面这个代码
    private void attach(boolean system, long startSeq) {
            final IActivityManager mgr = ActivityManager.getService();
            mgr.attachApplication(mAppThread, startSeq);//调用远端的binder
    }
  • 通过ActivityManager.getService()拿到system_server进程的binder,然后把mAppThread binder传递过去。mAppThreadApplicationThread的一个对象,是ActivityThread的一个内部类。
  • 取得联系后的第一站创建Applicaiton。
   private class ApplicationThread extends IApplicationThread.Stub {
        @Override
        public final void bindApplication() {
            sendMessage(H.BIND_APPLICATION, data);
        }
  • 接下来就是H主线程的Hanlder,调用handleBindApplication
 private void handleBindApplication(AppBindData data) {
        Application app;
        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo, isSdkSandbox);//内部创建LoadedApk
        app = data.info.makeApplicationInner(data.restrictedBackupMode, null);//内部创建Applicaiton对象,调用onCreate()方法
        installContentProviders(app, data.providers); //cotentprovider初始化
        mInstrumentation.callApplicationOnCreate(app);//调用onCreate()方法
    }
  • 这里找到了为什么使用ContentProvider能够实现初始化,构建的时候会创建ContenProvider。
 public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        String pkg = intent != null && intent.getComponent() != null
                ? intent.getComponent().getPackageName() : null;
        return getFactory(pkg).instantiateActivity(cl, className, intent);//加载创建Activity
    }

  • IActivityManager(binder):应用进程和SystemServer进程打交道的时候。
  • AppliactionThread(binder):SystemServer进程与应用进程通信。

2、为什么使用ContentProvider可以实现初始化

 private void handleBindApplication(AppBindData data) {
        Application app;
        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo, isSdkSandbox);//内部创建LoadedApk
        app = data.info.makeApplicationInner(data.restrictedBackupMode, null);//内部创建Applicaiton对象,调用onCreate()方法
        installContentProviders(app, data.providers); //cotentprovider初始化
        mInstrumentation.callApplicationOnCreate(app);//调用onCreate()方法
    }

上一段分析时已经找打了答案,应用进程被拉起来之后,在创建Application对象调用attachBaseContext()和onCreate()方法之间会调用ContentProvider的onCreate()方法这也是很多第三方SDK使用该特性实现初始化的原理。

3、Activity是什么时候开始渲染的

  public void handleResumeActivity() {
        performResumeActivity(r, finalStateRequest, reason)//调用Activity onResume
        final Activity a = r.activity;
        View decor = r.window.getDecorView();
        ViewManager wm = a.getWindowManager();
        a.mWindowAdded = true;
        wm.addView(decor, l);
   }

ActivityThread.javahandleResumeActivity()有这样一段代码,我们可以得出结论,Activity渲染的起点是在 onResume阶段,在onResume阶段会把decorView交给WindowManager开始执行渲染。

4、原来还可以监控组件的生命周期

class H extends Handler {

    public static final int RECEIVER                = 113; //广播接收者

    @UnsupportedAppUsage
    public static final int CREATE_SERVICE          = 114;//Service创建

    public static final int INSTALL_PROVIDER        = 145;//ContentProvider

    public static final int RELAUNCH_ACTIVITY = 160; //Activity启动

   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;
                handleBindApplication(data);
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                break;
            case RECEIVER:
                handleReceiver((ReceiverData)msg.obj);
                break;
            case CREATE_SERVICE:
                handleCreateService((CreateServiceData)msg.obj);
                break;
            case BIND_SERVICE:
                handleBindService((BindServiceData)msg.obj);
                break;

            case RELAUNCH_ACTIVITY:
                handleRelaunchActivityLocally((IBinder) msg.obj);
                break;
        }
    }
}

系统进程(system_server)指挥应用进程组件生命周期的第一站其实就在ActivityThread这里,交给H对象其实是主线程的Handler来分发处理,如上。我们可以反射拿到这一信息,可以监控到主线程对于这些组件调度的信息,这一信息对我们监控排查ANR很有帮助。

5 、SharedPreference被声讨的根源

 private void handleStopService(IBinder token) {
     QueuedWork.waitToFinish();      
 }
 public void handlePauseActivity(){
      QueuedWork.waitToFinish(); 
 }
 public void handleStopActivity(){
    QueuedWork.waitToFinish(); 
 }
public void handleServiceArgs(){
   QueuedWork.waitToFinish(); 
}

ActivityThread的以上方法里会调用 QueuedWork.waitToFinish(); 该代码会堵塞主线程执行等待SP的写入操作。这也是SP造成ANR的根源。

稍微展开点

   public static void waitToFinish() {
        while (true) {
                Runnable finisher;
                synchronized (sLock) {
                    finisher = sFinishers.poll();
                }
                if (finisher == null) {
                    break;
                }
                finisher.run();
            }
        } 
    }

waitToFinish()方法里有这样一段代码,sFinishers是一个List里面是存放的SP写入操作,会在SP执行commit和apply的时候放入进来。字节跳动团队就是在此处hook了使其poll()方法永远放回空,来杜绝此处产生的ANR。

7 、结

通过阅读ActivityThread的源码我们能在其中获取很多有用的知识。系统进程和应用进程通信的桥梁,Activity真正渲染的起始点,ContentProvider能实现SDK自动初始化的原理等都在ActivityThread看到他们的影子。


所以我们还更需要了解Framework 底层原理+具备性能优化的能力,这样才能体现出你的价值。因此在这为大家整合了这些:《Android 性能优化核心知识点手册》和《Android Framework核心知识点手册》,供大家进行复习参考学习:

《Android 性能调优核心笔记汇总》:https://qr18.cn/FVlo89

《Android 性能监控框架》:https://qr18.cn/FVlo89

《Android Framework核心知识点手册》:https://qr18.cn/AQpN4J

  1. 开机Init 进程
  2. 开机启动 Zygote 进程
  3. 开机启动 SystemServer 进程
  4. Binder 驱动
  5. AMS 的启动过程
  6. PMS 的启动过程
  7. Launcher 的启动过程
  8. Android 四大组件
  9. Android 系统服务 - Input 事件的分发过程
  10. Android 底层渲染 - 屏幕刷新机制源码分析
  11. Android 源码分析实战

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/513167.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于深度学习的动物识别系统的实现

项目介绍 动物识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对18种动物数据集进行训练,最后得到一个识别精度较高的模型。并基于Django框架,开发网页端操作平台&…

数据分析师 ---- SQL强化(3)

数据分析师 ---- SQL强化(3) 题目:每个月Top3的周杰伦歌曲 从听歌流水中找到18-25岁用户在2022年每个月播放次数top 3的周杰伦的歌曲 输入例子: drop table if exists play_log; create table play_log (fdate date,user_id int,song_id int ); inser…

前端的培训计划书

文章目录 导文模板一一、前言二、培训目标三、培训内容和计划 模板二模板三 导文 这里是导文 模板一 一、前言 随着互联网的快速发展,前端开发已经成为了现代软件开发中一个不可或缺的重要技能。本次培训旨在帮助学员快速掌握前端开发的核心知识和技能&#xff0c…

ChatGPT实现撰写邮件

撰写邮件 电子邮件是日常工作中很常用的工具,在相对正式的场合,一封格式美观、用语典雅的电子邮件正文会起到很好的作用。ChatGPT 可以较好的完成电子邮件的编写和格式美化工作。 下面让我们以产品销售的角度,写一封推销邮件。假定产品名称…

String类 [中]

目录 一、 string 的深浅拷贝 0x00 构造函数与析构函数的实现 0x01 拷贝构造 0x02 赋值 0x03 整体代码 二、 string的实现 0x01 引入 0x02 c_str 0x03 默认构造函数 三、size()与operator[]的实现 0x01 size()的实现 0x02 operator[]的实现 0x03 遍历实现 四、迭代器…

洛谷B2098 整数去重

整数去重 题目描述 给定含有 n n n 个整数的序列,要求对这个序列进行去重操作。所谓去重,是指对这个序列中每个重复出现的数,只保留该数第一次出现的位置,删除其余位置。 输入格式 输入包含两行: 第一行包含一个…

获取两个日期间时长 (XX天XX时XX分)

使用场景: 发货日期与到货日期 计算运输时长 代码: private String getMinuteTime(String startTime, String endTime) {String minuteTime null;if (StrUtil.isNotBlank(startTime) && StrUtil.isNotBlank(endTime)) {long minute DateUti…

【芯片设计- RTL 数字逻辑设计入门 2 - vcs 及 verdi 使用介绍】

文章目录 1.1 VCS 编译环境1.1.1 Complie Design1.1.2 simv 仿真 1.2 VCS 波形生成及查看1.2.1 verdi 命令介绍1.2.2 verdi 波形查看 1.1 VCS 编译环境 VCS 全称是 Verilog Compiler Simulator,是 Synopsys 公司的,类似于windows环境下的 questasim 或 …

Flink sql

1.创建表的执行环境 第一种 StreamExecutionEnvironment env StreamExecutionEnvironment.getExecutionEnvironment(); env.setParallelism(1); SingleOutputStreamOperator<Event> streamOperator env.addSource(new ClickSource()).assignTimestampsAndWatermarks(W…

深入理解C语言指针

目录 一、指针基础知识 二、野指针 三、指针运算 四、二级指针 五、指针数组与数组指针 六、函数指针与函数指针数组 一、指针基础知识 什么是指针&#xff1f; 指针其实就是个用来存放地址的变量&#xff0c;定义为type *。 指针大小&#xff1f; 32位平台(32个地…

【大数据-调度工具】dolphinscheduler安装和遇到的问题

1.安装 安装步骤按照官网安装即可 官网&#xff1a;DolphinScheduler | 文档中心 (apache.org) 版本&#xff1a;3.1.5 2.踩坑记录 Q1.大文件无法上传 问题描述&#xff1a; 在资源中心中上传文件选择完大文件夹之后&#xff0c;选择确认之后确认按钮转了几圈圈之后就没…

[Element]调整select样式

通过伪元素&#xff0c;实现这个和step长得差不多的样式 <template><el-selectv-model"value"placeholder"请选择提报单位"style"width: 430px"><el-optionv-for"(item, i) in officeList":class"el-option get…

hive的基本操作语句

背景&#xff1a;记录一下hive创建数据库&#xff0c;建表&#xff0c;添加数据&#xff0c;创建分区等的语句吧&#xff0c;省得总百度&#xff0c;&#x1f604; 第一步&#xff1a;hive的建库语句 create database pdata_dynamic;查看是否创建成功了 show databases;显示如…

Jenkins入门教程

一、开始使用 Jenkins 本导读将向您介绍使用 Jenkins、Jenkins 的主要特性和 Jenkins Pipeline 的基本知识。 本导读使用“独立”的 Jenkins 发行版&#xff0c;它可以在您自己本地的机器上运行。 准备工作 第一次使用 Jenkins&#xff0c;您需要&#xff1a; 机器要求&…

从入门到实践:计算机视觉图像分类完全指南

计算机视觉图像分类是计算机视觉领域的一个重要分支&#xff0c;它的目标是让计算机能够识别并分类不同的图像。在本文中&#xff0c;我们将介绍计算机视觉图像分类的基本概念、流程和常用算法。 一、图像分类的基本概念 图像分类是指将输入的图像自动分类到预定义的一组类别中…

量子计算+真实材料模拟!美国埃姆斯国家实验室科学家获得新突破

​ 噪声量子比特ADAPT仿真&#xff08;图片来源&#xff1a;网络&#xff09; 量子计算机的潜在功能远远超出当今的经典计算机&#xff0c;来自美国能源部埃姆斯国家实验室的科学家们展示了一种在材料研究中利用量子计算的新方法&#xff0c;通过模拟材料的自适应算法&#xf…

自参考和对比学习正则化的Few-shot医学图像分割

文章目录 Few-shot Medical Image Segmentation Regularized with Self-reference and Contrastive Learning摘要本文方法Local Prototype-Based SegmentationSelf-reference RegularizationContrastive LearningSuperpixel-Based Self-supervised Learning 实验结果 Few-shot …

分布式搜索引擎2——深入elasticsearch

数据聚合 聚合的分类 聚合(aggregations)可以实现对文档数据的统计、分析、运算。聚合常见的有三类: 桶(Bucket)聚合:用来对文档做分组 TermAggregation:按照文档字段值分组Date Histogram:按照日期阶梯分组&#xff0c;例如一周为一组&#xff0c;或者一月为一组 度量&…

第10章:数据处理增删改

一、插入数据 CREATE TABLE emp1 (id int(11) ,name varchar(15) ,hire_date date ,salary double(10,2) )1.添加一条数据 ①没有指明添加的字段&#xff0c;一定按照顺序添加 insert into emp1 values(1,wang,2000-4-4,5900)②指明添加的字段&#xff08;推荐&#xff09;…

【 图像水印 2019 CVPR】 StegaStamp 论文翻译

【 图像水印 2019 CVPR】 StegaStamp 论文翻译 论文题目&#xff1a;StegaStamp: Invisible Hyperlinks in Physical Photographs 中文题目&#xff1a;物理照片中不可见的超链接 论文链接&#xff1a;https://arxiv.org/abs/1904.05343 论文代码&#xff1a;https://github.co…