activitythread,activitythread创建
android activitythread 怎么启动
首先看一下Android系统的启动流程: bootloader 引导程序 kernel 内核 init init初始化(这个大家都比较熟悉了,不要多说) loads several daemons and services, including zygote see /init.rc and init..rc zygote 这个是占用时间最多的
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663) 该如何解决?
startActivity启动失败,主要原因是AndroidManifest.xml文件中没有注册对应的模块Activity导致的问题。如:
Intent intent = new Intent(this, RecordListActivity.class);
startActivity(intent);
主要问题是AndroidManifest.xml中没有注册对应的模块引起的,
AndroidManifest.xml中需增加:
activity android:name=".RecordListActivity"
/activity
Android 10.0 Activity的启动流程
本文主要学习记录,基于Android 10的源码,有错误欢迎指正,主要目的是梳理流程图。
以进程为单位的调用栈图如下:
1.activity中的startActivity方法最终都会通过拿到ATSM的代理IActivityTaskManager调用的startActivity;
2.之后进入system server进程中的ATMS startActivity,ATMS 经过收集Intent信息,然后使用ActivityStackSupervisor.startSpecificActivityLocked,如果进程已经存在,则直接使用realStartActivityLocked,通过App的binder客户端的代理ApplicationThread调用回到bindApplication,走入Activity的启动流程;如果进程不存在则通过socket链接Zygote,请求fork新的进程;
3.App进程创建完成后,进程启动会调用ActivityThread.main方法,初始化主线程Handler,接着走入attach方法,然后通过AMS的代理调用AMS的attachApplication方法,并将App进程的通信代理ApplicationThread传入AMS;
4.AMS获取到ATMS调用ApplicationThread的bindApplication回到App进程的ActivityThread.ApplicationThread.bindApplication方法中,然后使用Handler切换到主线程执行handleBindApplication,这里初始化了App的进程名字、时间,用户的硬件配置,包括App的文件系统,创建了App的Context实例,Instrumentation实例,调用App的onCreate回调方法,同时告诉AMS APP初始化工作完毕;
5.AMS接着会调用ATMS的attachApplication,最后调用ClientLifecycleManager的scheduleTransaction方法,通过App的Binder代理ApplicationThread回到ActivityThread;
6.进入ActivityThread.ApplicationThread.scheduleTransaction方法之后就进入了Activity的onStart、onResume回调
创建进程之前的过程主要是AMS的内部信息收集的判断的过程,下面主要看一下App进程启动的源码流程
从应用进程被创建开始,ActivityThread.main被执行
调用ActivityThread的attach方法,然后将activity和AMS通信的Binder代理IApplicationThread实例传入AMS
接着进入AMS进程,ActivityManagerService.attachApplicationLocked
1.thread.bindApplication :该方法主要讲App进程的配置信息通过IApplicationThread Binder通信回传到ActivityThread中
2.mAtmInternal.attachApplication :mAtmInternal实际就是ActivityTaskManager的实例,通过LocalServices加载
那么这里相当于走到了ActivityTaskManagerServer的attachApplication中
先看第一条:
注意:ActivityThread中存在于Binder通信的代理--》ApplicationThread extends IApplicationThread.Stub
ActivityThread--》ApplicationThread--》bindApplication
这里的bindApplication主要初始化了AppBindData,然后发送BIND_APPLICATION给APP的主线程BIND_APPLICATION,最后执行了handleBindApplication
handleBindApplication如下:
ActivityThread--》class H extends Handler
该方法主要在App进程中对App的一些硬件资源配置申请的属性、App的文件夹等完成App基本信息的初始化
接着看第二条:mAtmInternal.attachApplication
mAtmInternal.attachApplication最终会调用mRootActivityContainer.attachApplication(wpc)
RootActivityContainer.attachApplication
接着调用ActivityStackSupervisor.realStartActivityLocked开始创建Activity
ActivityStackSupervisor.realStartActivityLocked
创建ClientLifecycleManager和ClientTransactionHandler来辅助管理Activity的生命周期
注意
clientTransaction.addCallback是LaunchActivityItem
lifecycleItem是ResumeActivityItem
ClientLifecycleManager.scheduleTransaction最终会调用ClientTransaction的schedule方法
那么这个mClient是IApplicationThread的实例,那么此时也就回到了ActivityThread的ApplicationThread中
ActivityThread的ApplicationThread中
因为ActivityThread继承ClientTransactionHandler,所以到了ClientTransactionHandler中
通过Handler发送消息EXECUTE_TRANSACTION到H中
接着TransactionExecutor的execute方法
LaunchActivityItem.execute方法
client其实是在ActivityThread的实例,那么就回到了ActivityThread的handleLaunchActivity
接着调用performLaunchActivity
在performLaunchActivity中,主要是加载App的资源包,然后创建了Activity的context实例,并创建了Activity的实例,接着调用activity.attach方法,attach执行完之后调用了onCreate方法。
activity.attach
activity.attach中主要
1.创建了PhoneWindow实例
2.设置了Window接口的监听
3.初始化了成员变量,包括线程和WindowManager
到此Oncreate已经完成,那么OnStart和OnResume去哪了?
TransactionExecutor的execute方法
之前们只分析了executeCallbacks,接着executeLifecycleState方法
TransactionExecutor的executeLifecycleState方法
cycleToPath:lifecycleItem即为ResumeActivityItem
第一点:
int finish = lifecycleItem.getTargetState()
lifecycleItem对应ResumeActivityItem,如下:
ResumeActivityItem的getTargetState方法
对应ActivityLifecycleItem中的枚举类型:
第二点:ActivityClientRecord中的mLifecycleState,由于在前面已经执行了handleLaunchActivity所以mLifecycleState=1
对应ActivityLifecycleItem中的枚举类型:
PRE_ON_CREATE = 0
所以final int star = 1
接着看getLifecyclePath,此时start=1,finish=3
那么返回的IntArray就是2
接着看performLifecycleSequence
最终执行的是handleStartActivity所以最终走到了ActivityThread的handleResumeActivity
两点:
调用activity.performStart
调用Instrumetation.callActivityOnPostCreate
performStart方法:
调用了Instrumentation.callActivityOnStart方法:
最终到了activity的onStart方法
第二点:Instrumentation.callActivityOnPostCreate
上面主要走了cycleToPath,接着ResumeActivityItem.execute
调用了handleResumeActivity方法
handleResumeActivity最终调用performResumeActivity
调用了Instrumentation.callActivityOnResume,
到了activity.onResume()方法
参考文章:
Activity内存泄露的分析和解决
内存泄露:生命周期长的对象A引用了生命周期短的对象B。生命周期短的B对象已经完成了使用,原本可以被GC回收,但被生命周期长的对象A引用,导致不可被GC回收,从而出现B对象泄露。
常见原因:
影响:
通过AS的Leaked Activities 工具得到的数据
产生原因:
Activity被ActivityThread中的nextIdle(ActivityClientRecord)引用而出现了泄露!!!这个就有点意思了……
常规分析:
没有发现可疑的逻辑。
百度,google一番,没有发现有相同或类似的现象。
既然Activity是中ActivityThread中引用而导致泄露的,那就从ActivityThread的源码分析着手。
定位到Activity泄露的原因,解决就不复杂了。
activitythread main方法在哪儿调用
在一个Android 程序开始运行的时候,会单独启动一个Process。
默认的情况下,所有这个程序中的Activity或者Service(Service和 Activity只是Android提供的Components中的两种, 除此之外还有Content Provider和Broadcast Receiver)都会跑在这个Process。一个Android 程序默认情况下也只有一个Process,但一个Process下却可以有许多个Thread。
在这么多Thread当中,有一个Thread,我们称之为UI Thread。
UI Thread在Android程序运行的时候就被创建,是一个Process当中的主线程Main Thread, 主要是负责控制UI界面的显示、更新和控件交互。
在Android程序创建之初,一个Process呈现的是单线程模型,所有的任务都在一个线程中运行。因此,我们认为,UI Thread所执行的每一个函数,所花费的时间都应该是越短越好。而其他比较费时的工作(访问网络,下载数据,查询数据库等),都应该交由子线程去执行,以免阻塞主线程。
那么,UI Thread如何和其他Thread一起工作呢?常用方法是:
1.诞生一个主线程的Handler物件,当做Listener去让子线程能将讯息Push到主线程的Message Quene里,以便触发主线程的handlerMessage()函数,让主线程知道子线程的状态,并在主线程更新UI。
2.在子线程的状态发生变化时,我们需要更新UI。
如果在子线程中直接更新UI,通常会抛出下面的异常:
ERROR/JavaBinder(1029):android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views.
意思是,无法在子线程中更新UI。
3.我们需要通过Handler物件,通知主线程Ui Thread来更新界面。
ActivityThread
我们学习 Android 过程中会发现,我们的文件都是 .java 文件,也就是说 Android 开发还是用的 Java 语言来编写的。也正是这样,所以你们来学 Android ,也会让你们先学习一段时间 Java 。掌握好了 Java 的相关知识,学起 Android 来可谓是事半功倍。好了,你们是不是感觉有点扯远了啊,不是说好讲 ActivityThread 类的么,其实并不如此。
你们在刚开始从 Java 学习转到 Android 学习的过程中,有一个重大的改变不知道你们又没有发现。那就是 Java 中的 main() 方法,程序的入口不见了,取而代之的是 onCreate() 方法。你们没有一点疑惑么?初学阶段直接无脑接受是对的,但是作为一个工作几年了的人来说,就有必要去深入研究一下了。明明 Android 也就是 Java 语言也编写的,差别咋就这么大呢?
其实呢, Android 中还是有 main() 方法的,只是隐藏的比较深而已。今天,就由我 AIqingfeng 来带你们一探究竟~!
我们先找到 ActivityThread 这个类,看一下注释( 较少 ,值得一看):
翻译一下就是:在 Application 进程中 管理执行主线程,调度和执行 活动和广播 ,和活动管理请求的其它操作。
Android 上一个应用的入口,应该是 ActivityThread 类,和普通的Java 类一样,入口是一个 main() 方法。
好了,现在我们解决了我们开始的疑惑后,再来深度学习一下这个类的一些知识吧。
ActivityThread 有几个比较重要的成员变量,会在创建ActivityThread对象时初始化。
final ApplicationThread mAppThread = new ApplicationThread();
ApplicationThread继承自ApplicationThreadNative, 而ApplicationThreadNative又继承自Binder并实现了IApplicationThread接口。IApplicationThread继承自IInterface。这是一个很明显的binder结构,用于与Ams通信。IApplicationThread接口定义了对一个程序(Linux的进程)操作的接口。ApplicationThread通过binder与Ams通信,并将Ams的调用,通过下面的H类(也就是Hnalder)将消息发送到消息队列,然后进行相应的操作,入activity的start, stop。
final H mH = new H();
这个 H 大家首先会想到什么啊,不要开车哈。看到 H 想到了 Handler 。发现 H 是 ActivityThread 内部类,继承自 Handler ,果然没错。所以大家遇到不清楚的,不要怕,大胆的猜测一下。 Handler 最重要的的也就是 handleMessage() 方法了。查看一下其方法:
ActivityThread.java
点进来咯。 ActivityThread.java
兴趣是最好的老师。ActivityThread.java
先探索一下 Activity 创建这条路吧。最底层啦。Instrumentation.java
Native方法,C语言啦,活动创建之路结束了。Class.java
再来看看 Activity 中 onCreate() 方法执行之路吧。 Instrumentation.java
到了 Activity 了,哪里我们自己 Activity 还远么~! Activity.java
来,仔细瞅瞅~! Activity.java