Framework入门03-Activity组件

3-1 说说Activity的启动流程

启动Activity会经历哪些生命周期回调

冷启动大致流程,涉及哪些组件,通信过程是怎么样的?

Activity启动过程中,生命周期回调的原理?

Activity.startActivity -> ActivityManagerNative.getDefault().startActivity 这里的ActivityManagerNative.getDefault()是ams的binder对象,即代理对象 -> mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply,O) ams将请求写入binder驱动

-> binder驱动回调到ams的 onTransact()方法,然后根据请求码执行 startActivity(app, callingPackage, intent,...)

-> ams里处理activity的关键方法 startSpecificActivityLocked(),这个方法里,先判断应用进程是否启动(ProcessRecord app不为空且app.thread不为空时进程已启动),然后再执行真正启动activity的方法realStartActivityLocked(r, app...)

-> 如果进程未启动,则先启动进程 mService.startProcessLocked(r.processName...)

-> 将启动入口entryPoint="android.app.ActivityThread"通过socket发送给zygote, 然后 Process.start(entryPoint,) 即向zygote发送启动应用进程的请求。(这里大致说一下zygote启动应用进程的步骤:fork应用进程并返回pid,会返回两次:pid==0时在子进程,即应用进程执行;pid不为0时,在父进程执行,即将pid的值赋给ams,告诉ams应用进程已启动。)后面这里还会通过mHandler发送一条延迟消息,即延迟10s的超时消息,如果应用进程向ams报告自己已启动,则会移除这条消息,若是没有移除,处理这条消息时会清理进程的信息,即进程启动失败了。

-> 应用进程启动,在ActivityThread的main方法里,准备MainLooper;new ActivityThread;attach(false) false表示不可取消;loop死循环。

-> 上一步的attach(false)是跨进程调用:ActivityManagerNative.getDefault()获取ams的binder对象,attachApplication(mAppThread),参数mAppThread是applicationThread对象,这样asm就持有了应用进程的binder对象。

-> attachApplicationLocked(IApplicationThread thread, int pid) 这个方法很重要:thread.bindApplication(....)跨进程调用到应用进程,然后初始化application实例。之后就是启动acticity组件,启动service组件,启动广播。

-> 启动acticity组件的方法是mStackSupervisor.attachApplicationLocked(app),app是ProcessRecord实例

-> ActivityRecord hr = stack.topRunningActivityLocked(null);//是需要启动的activity,然后进入realStartActivityLocked(hr, app, true,true);

-> app.thread.scheduleLaunchActivity(new Intent(r.intent), ...); app是ProcessRecord,thread是ApplicationThread

-> sendMessage(H.LAUNCH ACTIVITY,r);//将要启动activity的message发送到主线程

-> 主线程处理message:final ActivityClientRecord r = (ActivityClientRecord) msg.obj;r.packagelnfo = getPackagelnfoNoCheck(.….); handleLaunchActivity(r, null);

-> 在handleLaunchActivity()里:Activity a = performLaunchActivity(r, customIntent);handleResumeActivity(r.token, false...);

-> 在performLaunchActivity()里,newActivity,获取application实例,创建上下文,activity.attach(),mlnstrumentation.callActivityOnCreate(activity, r.state);//即activity.onCreate()回调, activity.performStart();//即activity.onStart()回调;

-> 接着看handleLaunchActivity()方法,最终会回调activity.onResume();

3-2 说说Activity的显示原理

需理解以下的概念:

Activity的显示原理(Window/DecorView/ViewRoot)

Activity的UI刷新机制(Vsync信号/Choreographer机制) / ˌkɒriˈɒɡrəfə(r) / 编舞者,舞蹈指导

UI的绘制原理(Measure/Layout/Draw)

Surface原理(Surface/SurfaceFlinger)

说说Activity的显示原理,弄清楚以下3个问题:

setContentView原理是什么?

setContentView(layoutResID)

-> getWindow().setContentView(layoutResID) //getWindow()返回mWindow,是在activity的attach(context)里初始化的;

-> setContentView(int layoutReslD){

installDecor();//创建decorView,将系统布局添加到decorView,根据findViewById找到mContentParent,mContentParent是系统布局里的一个子布局;

mLayoutlnflater.inflate(layoutResID, mContentParent);//生成view tree,将viewTree加入到mContentParent里

}

Activity在onResume之后才会显示的原因是什么?

ViewRoot是干嘛的,是View Tree的rootView么?

在handleResumeActivity()方法里:

-> handleResumeActivity(lBinder token,) {

ActivityClientRecord r = performResumeActivity(token,); //执行onResume()回调

final Activity a = r.activity;

if (r.window == null && !a.mFinished) {

r.window = r.activity.getWindow();

View decor = r.window.getDecorView();

ViewManager wm = a.getWindowManager();

a.mDecor = decor;

wm.addView(decor,); //decor加入到windowManager

}

r.activity.makeVisible();//设置为可见,只是触发一次重绘

}

-> windowManager的addView()方法:

void addView(View view,ViewGroup.LayoutParams params,) {

ViewRootlmpl root = new ViewRootlmpl(view.getContext(),);

root.setView(yiew, wparams, panelParentView);//将decorView交给viewRoot来管理

}

-> setView(View view, ){

requestLayout(); //触发一次绘制

mWindowSession.addToDisplay(mWindow,..); //是binder调用,

}

-> 在requestLayout()方法里:

requestLayout ->scheduleTraversals()

-> mChoreographer.postCallback(... mTraversalRunnable, null)//在vsync信号来时执行回调doTraversal()

-> performTraversals() //执行绘制

private void performTraversals() {

//向wms申请surface,即执行mWindowSession.relayout(...,mSurface);

//relayout执行完后,mSurface就有值了,接下来的绘制就有了buffer,

//然后在buffer上绘制完了就提交给surfaceFlinger,surfaceFlinger合成好图像后,

//就能写到屏幕的缓冲区,然后页面就能显示出来了。

relayoutWindow(params,...);

performMeasure(childWidthMeasureSpec,

performLayout(lp, desiredWindowWidth, ...);

performDraw();

}

-> 再接着看mWindowSession.addToDisplay(mWindow,..);

viewRoot持有mWindowSession,mWindowSession是wms返回的一个binder对象,给应用和wms来通信用的;

mWindow是一个binder对象,注册到wms后,应用端与wms就构成了双向调用。

WMS主要作用:分配surface;掌管surface显示顺序及位置尺寸等;控制窗口动画;输入事件分发。

3-3 应用的UI线程是怎么启动的

什么是UI线程?

答:UI线程就是刷新Ul所在的线程;UI是单线程刷新的。

对Activity来说,UI线程就是主线程;

对View来说,它的UI线程就是ViewRootlmpl创建的时候所在的线程;

可以得出结论:Activity的DecorView对应的ViewRootlmpl是在主线程创建的。

UI线程的启动流程,消息循环是怎么创建的?

Zygote fork进程 -> 启动binder线程 -> 执行入口函数

ActivityThread.main()方法里:Looper.prepareMainLooper();Looper.loop();

了解Android的U显示原理,UI线程和UI之间是怎么关联的?

ViewRootlmpl的创建:

ActivityThread.handleResumeActivity -> WindowManagerlmpl.addView -> WindowManagerGlobal.addView -> ViewRootlmpl的构造

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

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

相关文章

《游戏编程模式》学习笔记(六)单例模式 Singleton Pattern

单例模式的定义 保证一个类只有一个实例,并且提供了访问该实例的全局访问点。 定义这种东西一般都是不说人话的,要想要理解这句话的意思,我们得把它揉开了才能搞明白。 我们先看前半句 “保证一个类只有一个实例”,单例一般使用…

jenkins pipeline方式一键部署github项目

上篇:jenkins一键部署github项目 该篇使用jenkins pipeline-script一键部署,且介绍pipeline-scm jenkins环境配置 前言:按照上篇创建pipeline任务,结果报mvn,jdk环境不存在,就很疑惑,然后配置全…

Lemon8与中国各大社交平台的内容输出整合,将会掀起何种风浪?

近期,Lemon8迅速在北美地区展开了布局,短短几天的时间,下载量就冲到了美国APP下载总榜的前十,随后更是直登顶生活类APP首榜。作为字节跳动旗下的出海内容平台,一经问世后,就受到了大量用户的关注,并吸引了海外媒体以及营销人士的目光。那么Lemon8与中国各大社交平台的内容输出整…

实战项目:基于主从Reactor模型实现高并发服务器

项目完整代码仿mudou库one thread one loop式并发服务器实现: 仿muduo库One Thread One Loop式主从Reactor模型实现⾼并发服务器:通过模拟实现的⾼并发服务器组件,可以简洁快速的完成⼀个⾼性能的服务器搭建。并且,通过组件内提供的不同应⽤层…

开发环境搭建

Anaconda安装搭建Python环境 官网下载Anaconda anaconda官网安装Anaconda设置系统环境变量 按照实际安装路径新建填写红框环境变量 验证环境是否正常运行 WINR输入cmd conda --version python --version pip --version 显示版本信息即为正常 VSCODE Python ShiftCtrlP顶部…

第六阶|见道明心的笔墨(上)从书法之美到生活之美——林曦老师的线上直播书法课

如果你有需要,可以找我的,我这边有老师的所有课程 如果你有需要,可以找我的,我这边有老师的所有课程

Less文件可以做哪些复杂操作

在Less文件中,你可以进行许多复杂的操作来增强样式表的功能和灵活性。以下是一些常见的操作: 变量(Variables):使用符号定义和使用变量,可以在整个样式表中重复使用相同的值,以便轻松修改和维护…

【NEW】视频云存储EasyCVR平台H.265转码配置增加分辨率设置

关于视频分析EasyCVR视频汇聚平台的转码功能,我们在此前的文章中也介绍过不少,感兴趣的用户可以翻阅往期的文章进行了解。 安防视频集中存储EasyCVR视频监控综合管理平台可以根据不同的场景需求,让平台在内网、专网、VPN、广域网、互联网等各…

抵御时代风险:高级安全策略与实践

目录 网页篡改攻击 流量攻击 数据库攻击 恶意扫描攻击 域名攻击 在今天的数字时代,网站已经成为企业、机构和个人展示信息、交流互动的重要平台。然而,随着网络攻击技术的不断进步,网站也面临着各种安全威胁。本文将探讨五种常见的网络攻…

【机器学习】— 2 图神经网络GNN

一、说明 在本文中,我们探讨了图神经网络(GNN)在推荐系统中的潜力,强调了它们相对于传统矩阵完成方法的优势。GNN为利用图论来改进推荐系统提供了一个强大的框架。在本文中,我们将在推荐系统的背景下概述图论和图神经网…

sqlite3将词典导入数据库

使用sqlite3代码实现将词典导入数据库中 #include <head.h> #include <sqlite3.h> #include <strings.h> #include <unistd.h> int main(int argc, const char *argv[]) {sqlite3 *db NULL;if(sqlite3_open("./dict.db",&db) ! SQLITE…

shell 简单且常用的几种

目录 一、配置环境的shell脚本 二、系统资源脚本 一、要求 二、脚本内容 三、脚本解析 四、赋权并验证 一、配置环境的shell脚本 systemctl stop firewalld systemctl disable firewalld systemctl stop NetworkManager systemctl disable NetworkManager setenforce…

vue3学习笔记

1.创建项目 2. 3.setup 4. 5. 6. 7.生命周期函数 8. 9. 10. 11. 12.pinia

企业如何为服务器找到合适的托管机房?

企业的服务器在业务经营中扮演着很重要的角色&#xff0c;提供可靠的数据存储和备份功能、计算能力和软件支持、网络通信连接等功能&#xff0c;是企业运行中关键的组成部分。因此&#xff0c;企业的服务器需要得到妥善的保管&#xff0c;为它们选择一个合适的托管机房十分有必…

IDEA下方工具栏SideBar没有Services解决方法 IDEA配合微服务学习多端口管理打开Services栏方法

问题 微服务学习时&#xff0c;一次要打开多个端口&#xff0c;比如8080给order模块、8081给user模块……这就需要用idea管理多端口。 这时候就可以用到Services栏进行管理。 解决 首先看下方Sidebar没有Services。 打开Services 打开方式一&#xff1a;手动打开 在IDEA中…

Vue--BM记事本

效果如下&#xff1a; 用到了如下的技术&#xff1a; 1.列表渲染&#xff1a;v-for key的设置 2.删除功能&#xff1a;v-on调用参数 fliter过滤 覆盖修改原数组 3.添加功能&#xff1a;v-model绑定&#xff0c;unshift修改原数组添加 html文件如下&#xff1a; <!DOCTYPE …

spring 缓存

1.spring缓存注解&#xff0c;可以丢在controller&#xff0c;也可以丢在service&#xff0c;也可以丢在mapper。 2.手动操作缓存使用&#xff1a; Autowiredprivate CacheManager cacheManager;3.添加缓存 //添加缓存 Override Cacheable(cacheNames "test", key…

Java面试宝典

目录 一、Java基础 1.JDK 和 JRE 的区别&#xff1f; 2. 和 equals 的区别&#xff1f; 3.hashCode() 和 equals() 的关系&#xff1f; 4. final 在 java 中的作用&#xff1f; 5.Math.round(-1.5) 的结果&#xff1f; 6.String 是否属于基础数据类型&#xff1f; 7.Jav…

互联网发展历程:保护与隔离,防火墙的安全壁垒

互联网的快速发展&#xff0c;不仅带来了便利和连接&#xff0c;也引发了越来越多的安全威胁。在数字时代&#xff0c;保护数据和网络安全变得尤为重要。然而&#xff0c;在早期的网络中&#xff0c;安全问题常常让人担忧。 安全问题的困扰&#xff1a;网络威胁日益增加 随着互…

工厂方法模式【Factory Method Pattern】

前言 1.工厂模式概念 实例化对象&#xff0c;用工厂方法代替new操作(重点) 工厂模式包括工厂方法模式和抽象工厂模式 抽象工厂模式是工厂方法模式的扩展 2.什么情况下适合工厂模式 有一组类似的对象需要创建 在编码时不能预见需要创建哪种类的实例 系统需要考虑扩展性&#xff…