ActivityThread在Android中它就代表了Android的主线程,但是并不是一个Thread类。

严格来说,UI主线程不是ActivityThread。ActivityThread类是Android APP进程的初始类,它的main函数是这个APP进程的入口。APP进程中UI事件的执行代码段都是由ActivityThread提供的。也就是说,Main Thread实例是存在的,只是创建它的代码我们不可见。ActivityThread的main函数就是在这个Main Thread里被执行的。

1.Java程序初始类中的main()方法,将作为该程序初始线程的起点,任何其他的线程都是由这个初始线程启动的。这个线程就是程序的主线程。
2.在Thread.java文件头部的说明中,有这样的介绍:Each application has at least one thread running when it is started, the main thread, in the main {@link ThreadGroup}.

源码如下:

http://androidxref.com/6.0.0_r1/xref/frameworks/base/core/java/android/app/ActivityThread.java

  1. public final class ActivityThread {
  2. //... 
  3. final H mH = new H();
  4. final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
  5. final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
  6.  
  7. final ApplicationThread mAppThread = new ApplicationThread();  
  8. private class ApplicationThread extends ApplicationThreadNative {    
  9.        //...
  10. }
  11. private class H extends Handler {
  12. //...
  13. }
  14. //...
  15. }

1.ActivityThread.main()

  1. public final class ActivityThread {
  2.  
  3. //...
  4. private static ActivityThread sCurrentActivityThread;
  5. public static ActivityThread currentActivityThread() {
  6. return sCurrentActivityThread;
  7. }
  8. private void attach(boolean system) {
  9. sCurrentActivityThread = this;
  10. //...
  11. }
  12. public static void main(String[] args) {
  13. //....
  14.  
  15. //创建Looper和MessageQueue对象,用于处理主线程的消息
  16. Looper.prepareMainLooper();
  17.  
  18. //创建ActivityThread对象
  19. ActivityThread thread = new ActivityThread();
  20.  
  21. //建立Binder通道 (创建新线程)
  22. thread.attach(false);
  23.  
  24. Looper.loop(); //消息循环运行
  25. throw new RuntimeException("Main thread loop unexpectedly exited");
  26. }
  27.  
  28. }

new ActivityThread()的局部变量通过attach()方法变成了全局变量sCurrentActivityThread,

通过currentActivityThread()方法可以得到当前线程

  1. private void attach(boolean system) {
  2. sCurrentActivityThread = this;
  3. mSystemThread = system;
  4. if (!system) {
  5. //将mAppThread放到RuntimeInit类中的静态变量,也就是ApplicationThreadNative中的 this
  6. RuntimeInit.setApplicationObject(mAppThread.asBinder());
  7. final IActivityManager mgr = ActivityManagerNative.getDefault();
  8. try {
  9. mgr.attachApplication(mAppThread); //将mAppThread传入ActivityManagerService中
  10. } catch (RemoteException ex) {
  11. // Ignore
  12. }
  13. // Watch for getting close to heap limit.
  14. BinderInternal.addGcWatcher(new Runnable() {
  15. @Override public void run() {
  16. //...
  17. }
  18. });
  19. } else {
  20. // Don't set application object here -- if the system crashes,
  21. // we can't display an alert, we just want to die die die.
  22. android.ddm.DdmHandleAppName.setAppName("system_process",
  23. UserHandle.myUserId());
  24. try {
  25. mInstrumentation = new Instrumentation();
  26. ContextImpl context = ContextImpl.createAppContext(
  27. this, getSystemContext().mPackageInfo);
  28. mInitialApplication = context.mPackageInfo.makeApplication(true, null);
  29. mInitialApplication.onCreate();
  30. } catch (Exception e) {
  31. throw new RuntimeException(
  32. "Unable to instantiate Application():" + e.toString(), e);
  33. }
  34. }
  35.  
  36. //...
  37. }

1.调用 RuntimeInit.setApplicationObject() 方法,把对象mAppThread(Binder)放到了RuntimeInit类中的静态变量mApplicationObject中。

mAppThread的类型是ApplicationThread,它是ActivityThread的成员变量,定义和初始化如下:

  1. final ApplicationThread mAppThread = new ApplicationThread();
2.调用ActivityManagerService的attachApplication()方法,将mAppThread 作为参数传入ActivityManagerService,这样ActivityManagerService就可以调用ApplicaitonThread的接口了。这与我们刚才说的,ActivityManagerService作为Client端调用ApplicaitonThread的接口管理Activity,就不谋而合了。

2.ActivityThread与是怎么启动Activity呢?

ActivityThread的final H mH = new H()内部类H继承于Handler,通过handler消息机制,简单说Handler机制用于同一个进程的线程间通信。

  Activity的生命周期都是依靠主线程的Looper.loop,当收到不同Message时则采用相应措施:
   在H.handleMessage(msg)方法中,根据接收到不同的msg,执行相应的生命周期

例如:

当msg.what == LAUNCH_ACTIVITY就是调用handleLaunchActivity方法启动一个Activity,在handleLaunchActivity中又调用了performLaunchActivity方法来创建一个Activity实例,完成Activity的启动。 handleLaunchActivity源码如下:

  1. private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
  2. //...调用performLaunchActivity方法完成Activity的启动
  3. Activity a = performLaunchActivity(r, customIntent);
  4. //...
  5. }

H继承与Handle,重写了handleMessage的方法

  1. public final class ActivityThread {
  2. //... 
  3. final H mH = new H();
  4.  
  5. private class H extends Handler {
  6. //...声明的一些常量
  7. public void handleMessage(Message msg) {
  8. //...
  9. switch (msg.what) {
  10. //针对不同的常量,做不同的业务处理
  11. case LAUNCH_ACTIVITY: {
  12. //...启动一个Activity
  13. handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
  14. //...
  15. } break;
  16. case RELAUNCH_ACTIVITY: {
  17. //...
  18. handleRelaunchActivity(r);
  19. //...
  20. } break;
  21. case PAUSE_ACTIVITY: {
  22. //...
  23. handlePauseActivity((IBinder) args.arg1, false,
  24. (args.argi1 & USER_LEAVING) != 0, args.argi2,
  25. (args.argi1 & DONT_REPORT) != 0, args.argi3);
  26. maybeSnapshot();
  27. //...
  28. } break;
  29. //...
  30. }
  31. //...
  32. }
  33.  
  34. private void maybeSnapshot() {
  35. //...这个方法主要统计snapshot
  36. }
  37. }
  38. }

这个类主要作用就是根据不同的情况处理各种业务,而且处理业务的方法一般是以handle开头,handleXXX的格式,如下:

  1. handleActivityConfigurationChanged()
  2. handleBindApplication()
  3. handleBindService()
  4. handleCancelVisibleBehind()
  5. handleConfigurationChanged()
  6. handleCreateService()
  7. handleDestroyActivity()
  8. handleDispatchPackageBroadcast()
  9. handleLaunchActivity()
  10. handleLowMemory()
  11. handleMessage()
  12. handleNewIntent()
  13. handlePauseActivity()
  14. handleReceiver()
  15. handleRelaunchActivity()
  16. handleResumeActivity()
  17. handleSendResult()
  18. handleServiceArgs()
  19. handleStopActivity()
  20. handleStopService()

而这些函数有的又会调用到如下的performXXX系列函数完成最终的事件处理:

  1. performDestroyActivity()
  2. performDestroyActivity()
  3. performLaunchActivity()
  4. performNewIntents()
  5. performPauseActivity()
  6. performPauseActivity()
  7. performRestartActivity()
  8. performResumeActivity()
  9. performStopActivity()
  10. performStopActivityInner()
  11. performUserLeavingActivity()

 例如 从栈顶Activity的onPause到启动activityon的Resume过程

  1. ActivityStack.startPausingLocked()
  2. IApplicationThread.schedulePauseActivity()
  3. ActivityThread.sendMessage()
  4. ActivityThread.H.sendMessage();
  5. ActivityThread.H.handleMessage()
  6. ActivityThread.handlePauseActivity()
  7. ActivityThread.performPauseActivity()
  8. Activity.performPause()
  9. Activity.onPause()
  10. ActivityManagerNative.getDefault().activityPaused(token)
  11. ActivityManagerService.activityPaused()
  12. ActivityStack.activityPausedLocked()
  13. ActivityStack.completePauseLocked()
  14. ActivityStack.resumeTopActivitiesLocked()
  15. ActivityStack.resumeTopActivityLocked()
  16. ActivityStack.resumeTopActivityInnerLocked()
  17. ActivityStack.startSpecificActivityLocked

一般都是执行scheduleXXXActivity

然后ActivityThread sendMessage到handleMessage 然后handleXXXActivvity,最后处理performXXXActivity

3.主线程的消息又是哪来的呢?

当然是App进程中的其他线程通过Handler发送给主线程

  

ActivityThread框架是基于Binder通信的C/S结构,从图可知Server端是ActivityThread、ApplicationThread,Client是AMS(ActivityManagerService),而ApplicationThreadProxy可以看作AMS中Server代表

system_server进程是系统进程,java framework框架的核心载体,里面运行了大量的系统服务,比如这里提供ApplicationThreadProxy,ActivityManagerService,这个两个服务都运行在system_server进程的不同线程中,由于ApplicationThreadProxy和ActivityManagerService都是基于IBinder接口,都是binder线程,binder线程的创建与销毁都是由binder驱动来决定的。

App进程则是我们常说的应用程序,主线程主要负责Activity/Service等组件的生命周期以及UI相关操作都运行在这个线程; 另外,每个App进程中至少会有两个binder线程 ApplicationThread和ActivityManagerProxy,除了图中画的线程,其中还有很多线程,比如signal catcher线程等,这里就不一一列举。

Binder用于不同进程之间通信,由一个进程的Binder客户端向另一个进程的服务端发送事务,比如图中线程2向线程4发送事务;而handler用于同一个进程中不同线程的通信,比如图中线程4向主线程发送消息。

例如:

需要暂停一个Activity

  • 线程1的AMS中调用线程2的ApplicationThreadProxy;(由于同一个进程的线程间资源共享,可以相互直接调用,但需要注意多线程并发问题)
  • 线程2通过binder传输到App进程的线程4;
  • 线程4通过handler消息机制,将暂停Activity的消息发送给主线程;
  • 主线程在looper.loop()中循环遍历消息,当收到暂停Activity的消息时,便将消息分发给ActivityThread.H.handleMessage()方法,再经过方法的调用,最后便会调用到Activity.onPause(),当onPause()处理完后,继续循环loop下去。

4.ApplicationThread

ActivityThread与启动Activity有关,那么ApplicationThread就与启动Application有关了

ApplicationThread是ActivityThread的内部类,继承ApplicationThreadNative,也是一个Binder对象。在此处它是作为IApplicationThread对象的server端等待client端的请求然后进行处理,最大的client就是AMS.

  1. private class ApplicationThread extends ApplicationThreadNative {
  2. //...
  3. schedulePauseActivity()
  4. scheduleStopActivity()
  5. scheduleResumeActivity()
  6. scheduleSendResult()
  7. scheduleLaunchActivity()
  8. scheduleNewIntent()
  9. scheduleDestroyActivity()
  10. scheduleReceiver()
  11. scheduleCreateService()
  12. scheduleBindService()
  13. scheduleUnbindService()
  14. scheduleServiceArgs()
  15. scheduleStopService()
  16. bindApplication()
  17. scheduleConfigurationChanged()
  18. scheduleRegisteredReceiver()
  19. scheduleInstallProvider()
  20. }

可以看出来它继承了ApplicationThreadNative的,并且它内部有非常多的scheduleXXX的方法.以后看到thread调用这个方法 就可以往这边找。我们先说一下这些方法,这些方法由外部的ActivityThread的binder远程代理对象调用最终走到这里.这些 schedulexxx的方法会进一步的通过往外发送消息给mH这个消息队列.来做处理

IApplicationThread

http://androidxref.com/6.0.0_r1/xref/frameworks/base/core/java/android/app/IApplicationThread.java

可以看到ApplicationThreadNative和ApplicationThreadProxy都实现了这个接口

  1. public interface IApplicationThread extends IInterface {
  2. void schedulePauseActivity() throws RemoteException;
  3. void scheduleStopActivity() throws RemoteException;
  4. void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
  5. void scheduleSleeping() throws RemoteException;
  6. void scheduleResumeActivity() throws RemoteException;
  7. void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
  8. void scheduleLaunchActivity() throws RemoteException;
  9. void scheduleRelaunchActivity() throws RemoteException;
  10. void scheduleNewIntent() throws RemoteException;
  11. void scheduleReceiver() throws RemoteException;
  12.  
  13. void scheduleCreateBackupAgent() throws RemoteException;
  14. void scheduleDestroyBackupAgent()throws RemoteException;
  15. void scheduleCreateService() throws RemoteException;
  16. void scheduleBindService() throws RemoteException;
  17. void scheduleUnbindService() throws RemoteException;
  18. void scheduleServiceArgs() throws RemoteException;
  19. void scheduleStopService() throws RemoteException;
  20. void bindApplication() throws RemoteException;
  21. void scheduleExit() throws RemoteException;
  22. void scheduleSuicide() throws RemoteException;
  23. void scheduleConfigurationChanged() throws RemoteException;
  24.  
  25. //...
  26. }

在来看看ApplicationThreadNative这个类

详细源码如下:
http://androidxref.com/6.0.0_r1/xref/frameworks/base/core/java/android/app/ApplicationThreadNative.java

  1. public abstract class ApplicationThreadNative extends Binder implements IApplicationThread {
  2. //根据传入的不同参数决定返回不同的值.
  3. static public IApplicationThread asInterface(IBinder obj) {
  4. if (obj == null) {
  5. return null;
  6. }
  7. IApplicationThread in =
  8. (IApplicationThread)obj.queryLocalInterface(descriptor);
  9. if (in != null) {
  10. return in;
  11. }
  12.  
  13. return new ApplicationThreadProxy(obj);
  14. }
  15. public ApplicationThreadNative() {
  16. attachInterface(this, descriptor);
  17. }
  18. @Override
  19. public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
  20. throws RemoteException {
  21. switch (code) {
  22. //...
  23. }
  24. }
  25.  
  26. public IBinder asBinder(){
  27. return this;
  28. }
  29.  
  30. }

说明:
      该类实现业务接口IApplicationThread,非常标准的Binder模板.IApplicationThread extends IInterface它里面就是定义了非常多的通信的业务接口,也都是schedulexxx理解上对应到ApplicationThread那些方法。
      该类首先是提供了一个静态的方法asInterface()用来获取IApplicationThread的Binder对象或者Binder代理对象,其它进程跨进程调用时候当传入的是BinderProxy那么就会返回一个ApplicationThreadProxy对象并把BinderProxy传入它的构造,而一般在本进程中调用的时候,就直接返回当前IApplicationThread对象,然后就是onTransact()函数了,里面通过不同的code对应到不同的case,进而调用不同的schedulexxx的方法,最终调用ApplicationThread中的schedulexxx方法。ApplicationThread这样就完成了作为服务端的构架,接下来就就是代理端的分析了.

前面我们知道跨进程调用asInterface的时候返回的是ApplicationThreadProxy对象,该类位于ApplicationThreadNative.java文件当中,是其内部类

ApplicationThreadProxy

  1. public abstract class ApplicationThreadNative extends Binder
  2. implements IApplicationThread {
  3. //...
  4. class ApplicationThreadProxy implements IApplicationThread {
  5.  
  6. private final IBinder mRemote;
  7.  
  8. public ApplicationThreadProxy(IBinder remote) {
  9. mRemote = remote;
  10. }
  11.  
  12. public final IBinder asBinder() {
  13. return mRemote;
  14. }
  15.  
  16. public final void schedulePauseActivity(IBinder token, boolean finished,
  17. boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {
  18. Parcel data = Parcel.obtain();
  19. data.writeInterfaceToken(IApplicationThread.descriptor);
  20. data.writeStrongBinder(token);
  21. data.writeInt(finished ? 1 : 0);
  22. data.writeInt(userLeaving ? 1 : 0);
  23. data.writeInt(configChanges);
  24. data.writeInt(dontReport ? 1 : 0);
  25. mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
  26. IBinder.FLAG_ONEWAY);
  27. data.recycle();
  28. }
  29.  
  30. public final void scheduleStopActivity(IBinder token, boolean showWindow,
  31. int configChanges) throws RemoteException {
  32. //...
  33. }
  34. //...一些列的schedulexxx
  35.  
  36. }
  37. }

说明,也是代理端的标准实现,实现了IApplicationThread 接口,然后实现接口中定义的业务方法,在每个方法中最终调用到了服务端的对应的schedulexxx方法中。当然这个过程是通过Binder通信调用的,例如上面通过mRemote变量和驱动去交互进而调用到server端, mRemote是一个BinderProxy对象.
       关于IApplicationThread的Binder相关实现,有个需要注意的它没有趣ServiceManager中注册,走的是一个匿名的binder的方法,其实对于驱动来说都一样.暂时发现的是别的地方如AMS用的时候通过ActivityThread的接口获得到ApplicationThread的对象,然后传入到asInterface(),获取对应的IApplicationThread对象进行跨进程调用。

android主线程ActivityThread的更多相关文章

  1. Android ActivityThread(主线程或UI线程)简介

    1. ActivityThread功能 它管理应用进程的主线程的执行(相当于普通Java程序的main入口函数),并根据AMS的要求(通过IApplicationThread接口,AMS为Client ...

  2. Android更新主线程UI的两种方式handler与runOnUiThread()

    在android开发过程中,耗时操作我们会放在子线程中去执行,而更新UI是要主线程(也叫做:UI线程)来更新的,自然会遇到如何更新主线程UI的问题.如果在主线程之外的线程中直接更新页面显示常会报错.抛 ...

  3. Android判断当前是否在主线程

    Android开发中, 有时需要判断当前线程到底是主线程, 还是子线程, 例如: 我们在自定义View时, 想要让View重绘, 需要先判断当前线程到底是不是主线程, 然后根据判断结果来决定到底是调用 ...

  4. Android Handler 异步调用修改界面与主线程

    在Android编程的过程中,如果在Activity中某个操作会运行比较长的时间,比如:下载文件.这个时候如果在主线程中直接下载文件,会造成Activity卡死的现象:而且如果时间超过5秒,会有ANR ...

  5. Android 线程与主线程

    网络连接需要时间.Web服务器可能需要1~2秒的时间来响应,文件下载则耗时更久.考虑到这个因素,Android禁止任何主线程网络连接行为.即使强行为之,Android也会抛出NetworkOnMain ...

  6. 2017-11-29 由runnable说起Android中的子线程和主线程

    1.首先纠正一个观点,就是runnable运行在子线程中是错误的观念.runnable只是创建了一个执行任务的对象,但是它本身并不会创建一个新的子线程,Runable只是给你接口让你实现工作线程的工作 ...

  7. android的子线程切换到主线程

    在子线程中,如果想更新UI,必须切换到主线程,方法如下: if (Looper.myLooper() != Looper.getMainLooper()) { // If we finish mark ...

  8. android 进程/线程管理(一)----消息机制的框架

    一:android 进程和线程 进程是程序运行的一个实例.android通过4大主件,弱化了进程的概念,尤其是在app层面,基本不需要关系进程间的通信等问题. 但是程序的本质没有变,尤其是多任务系统, ...

  9. Android子线程真的不能更新UI么

    Android单线程模型是这样描述的: Android UI操作并不是线程安全的,并且这些操作必须在UI线程执行 如果在其它线程访问UI线程,Android提供了以下的方式: Activity.run ...

随机推荐

  1. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(1):Mybatis和Hibernate概念理解

    一.关键字说明: oop:面向对象 aop:面向切面 ioc:控制反转 orm:对象关系映射 pojo:数据库表映射的java实体类 二.常识说明:1.hibernate和mybatis都属于持久层. ...

  2. 编写高质量代码改善C#程序的157个建议——建议60:重新引发异常时使用Inner Exception

    建议60:重新引发异常时使用Inner Exception 当捕获了某个异常,将其包装或重新引发异常的时候,如果其中包含了Inner Exception,则有助于程序员分析内部信息,方便代码调试. 以 ...

  3. springMVC传对象参数

    springController: [java] view plaincopy @Controller @RequestMapping("/user") public UserCo ...

  4. 解决iReport打不开的一种方法

    解决iReport打不开的一种方法 iReport版本:iReport-5.6.0-windows-installer.exe 系统:Win7 64位 JDK:1.7 在公司电脑安装没问题,能打开,但 ...

  5. Android下拉选择框之PopupWindow

    1.效果图 2.思路分析 1.点击弹出对话框 popupwindow 2.对popupwindow进行相关设置,popupwindow中设置view为listview 3.listview中item设 ...

  6. 下载Chrome浏览器离线安装包

    下面提供了window和Mac OS两个版本的Chrome离线版本: Windows版本 Mac OS版本 说明 基本格式是在 chrome 首页的链接 https://www.google.com/ ...

  7. 从头开始学eShopOnContainers——开发环境要求

    一.简介 eShopOnContainers是一个简化版的基于.NET Core和Docker等技术开发的面向微服务架构的参考应用,是一个简化版的在线商城/电子商务应用,其包含基于浏览器的Web应用. ...

  8. 类的互相包含------新标准c++程序设计

    #include<iostream> using namespace std; class A; class B{ public: void f(A* pt){}; } class A{ ...

  9. git you need to resolve your current index first 解决办法

    当使用git checkout 切换分支时会提示you need to resolve your current index first,使用如下命令即可解决. $ git reset --merge

  10. 洛谷P4502 [ZJOI2018]保镖(计算几何+三维凸包)

    题面 传送门 题解 我对计蒜几盒一无所知 顺便\(xzy\)巨巨好强 前置芝士 三维凸包 啥?你不会三维凸包?快去把板子写了->这里 欧拉公式 \[V-E+F=2\] \(V:vertex\)顶 ...