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

public final class ActivityThread {
//... 
final H mH = new H();
final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();final ApplicationThread mAppThread = new ApplicationThread();  private class ApplicationThread extends ApplicationThreadNative {    //...
  }private class H extends Handler {//...
  }
//...
}  

1.ActivityThread.main()

public final class ActivityThread {//...private static ActivityThread sCurrentActivityThread;public static ActivityThread currentActivityThread() {return sCurrentActivityThread;}private void attach(boolean system) {sCurrentActivityThread = this;//...
    }
   public static void main(String[] args) {//....//创建Looper和MessageQueue对象,用于处理主线程的消息
        Looper.prepareMainLooper();//创建ActivityThread对象ActivityThread thread = new ActivityThread(); //建立Binder通道 (创建新线程)thread.attach(false);Looper.loop(); //消息循环运行throw new RuntimeException("Main thread loop unexpectedly exited");}}

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

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

   private void attach(boolean system) {sCurrentActivityThread = this;mSystemThread = system;if (!system) {//将mAppThread放到RuntimeInit类中的静态变量,也就是ApplicationThreadNative中的 this
            RuntimeInit.setApplicationObject(mAppThread.asBinder());final IActivityManager mgr = ActivityManagerNative.getDefault();try {mgr.attachApplication(mAppThread); //将mAppThread传入ActivityManagerService中} catch (RemoteException ex) {// Ignore
            }// Watch for getting close to heap limit.BinderInternal.addGcWatcher(new Runnable() {@Override public void run() {//...
                }});} else {// Don't set application object here -- if the system crashes,// we can't display an alert, we just want to die die die.android.ddm.DdmHandleAppName.setAppName("system_process",UserHandle.myUserId());try {mInstrumentation = new Instrumentation();ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);mInitialApplication = context.mPackageInfo.makeApplication(true, null);mInitialApplication.onCreate();} catch (Exception e) {throw new RuntimeException("Unable to instantiate Application():" + e.toString(), e);}}//...}

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

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

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源码如下:

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

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

public final class ActivityThread {
//... 
final H mH = new H();private class H extends Handler {//...声明的一些常量public void handleMessage(Message msg) {//...switch (msg.what) {//针对不同的常量,做不同的业务处理case LAUNCH_ACTIVITY: {//...启动一个ActivityhandleLaunchActivity(r, null, "LAUNCH_ACTIVITY");//...} break;case RELAUNCH_ACTIVITY: {//...
                    handleRelaunchActivity(r);//...} break;case PAUSE_ACTIVITY: {//...handlePauseActivity((IBinder) args.arg1, false,(args.argi1 & USER_LEAVING) != 0, args.argi2,(args.argi1 & DONT_REPORT) != 0, args.argi3);maybeSnapshot();//...} break;//...
            }//...
        }private void maybeSnapshot() {//...这个方法主要统计snapshot
        }}
} 

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

handleActivityConfigurationChanged()
handleBindApplication()
handleBindService()
handleCancelVisibleBehind()
handleConfigurationChanged()
handleCreateService()
handleDestroyActivity()
handleDispatchPackageBroadcast()
handleLaunchActivity()
handleLowMemory()
handleMessage()
handleNewIntent()
handlePauseActivity()
handleReceiver()
handleRelaunchActivity()
handleResumeActivity()
handleSendResult()
handleServiceArgs()
handleStopActivity()
handleStopService()

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

performDestroyActivity()
performDestroyActivity()
performLaunchActivity()
performNewIntents()
performPauseActivity()
performPauseActivity()
performRestartActivity()
performResumeActivity()
performStopActivity()
performStopActivityInner()
performUserLeavingActivity()

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

ActivityStack.startPausingLocked()
IApplicationThread.schedulePauseActivity()
ActivityThread.sendMessage()
ActivityThread.H.sendMessage();
ActivityThread.H.handleMessage()
ActivityThread.handlePauseActivity()
ActivityThread.performPauseActivity()
Activity.performPause()
Activity.onPause()
ActivityManagerNative.getDefault().activityPaused(token)
ActivityManagerService.activityPaused()
ActivityStack.activityPausedLocked()
ActivityStack.completePauseLocked()
ActivityStack.resumeTopActivitiesLocked()
ActivityStack.resumeTopActivityLocked()
ActivityStack.resumeTopActivityInnerLocked()
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.

private class ApplicationThread extends ApplicationThreadNative {//...
    schedulePauseActivity()scheduleStopActivity()scheduleResumeActivity()scheduleSendResult()scheduleLaunchActivity()scheduleNewIntent()scheduleDestroyActivity()scheduleReceiver()scheduleCreateService()scheduleBindService()scheduleUnbindService()scheduleServiceArgs()scheduleStopService()bindApplication()scheduleConfigurationChanged()scheduleRegisteredReceiver()scheduleInstallProvider()
}

可以看出来它继承了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都实现了这个接口

public interface IApplicationThread extends IInterface {void schedulePauseActivity() throws RemoteException;void scheduleStopActivity() throws RemoteException;void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;void scheduleSleeping() throws RemoteException;void scheduleResumeActivity() throws RemoteException;void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;void scheduleLaunchActivity() throws RemoteException;void scheduleRelaunchActivity() throws RemoteException;void scheduleNewIntent() throws RemoteException;void scheduleReceiver() throws RemoteException;void scheduleCreateBackupAgent() throws RemoteException;void scheduleDestroyBackupAgent()throws RemoteException;void scheduleCreateService() throws RemoteException;void scheduleBindService() throws RemoteException;void scheduleUnbindService() throws RemoteException;void scheduleServiceArgs() throws RemoteException;void scheduleStopService() throws RemoteException;void bindApplication() throws RemoteException;void scheduleExit() throws RemoteException;void scheduleSuicide() throws RemoteException;void scheduleConfigurationChanged() throws RemoteException;//...
}

在来看看ApplicationThreadNative这个类

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

public abstract class ApplicationThreadNative extends Binder implements IApplicationThread {//根据传入的不同参数决定返回不同的值.static public IApplicationThread asInterface(IBinder obj) {if (obj == null) {return null;}IApplicationThread in =(IApplicationThread)obj.queryLocalInterface(descriptor);if (in != null) {return in;}return new ApplicationThreadProxy(obj);}public ApplicationThreadNative() {attachInterface(this, descriptor);}@Overridepublic boolean onTransact(int code, Parcel data, Parcel reply, int flags)throws RemoteException {switch (code) {//...
        }}public IBinder asBinder(){return this;} }

说明:
      该类实现业务接口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

public abstract class ApplicationThreadNative extends Binderimplements IApplicationThread {//...class ApplicationThreadProxy implements IApplicationThread {private final IBinder mRemote;public ApplicationThreadProxy(IBinder remote) {mRemote = remote;}public final IBinder asBinder() {return mRemote;}public final void schedulePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {Parcel data = Parcel.obtain();data.writeInterfaceToken(IApplicationThread.descriptor);data.writeStrongBinder(token);data.writeInt(finished ? 1 : 0);data.writeInt(userLeaving ? 1 : 0);data.writeInt(configChanges);data.writeInt(dontReport ? 1 : 0);mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,IBinder.FLAG_ONEWAY);data.recycle();}public final void scheduleStopActivity(IBinder token, boolean showWindow,int configChanges) throws RemoteException {//...
        }//...一些列的schedulexxx
}
}

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

转载于:https://www.cnblogs.com/mingfeng002/p/10323668.html

android主线程ActivityThread相关推荐

  1. activitythread.java,android主线程ActivityThread

    ActivityThread在Android中它就代表了Android的主线程,但是并不是一个Thread类. 严格来说,UI主线程不是ActivityThread.ActivityThread类是A ...

  2. android主线程报ANR的问题!

    ANR (Application Not Responding) 默认情况下,在android中Activity的最长执行时间是5秒,BroadcastReceiver的最长执行时间则是10秒. 第一 ...

  3. Looper 需要手动 quit,那主线程 Looper 呢?

    我们都清楚自行启动 Looper 的线程,在任务结束时需要手动调用 quit() 或 quitSafely() 终止 Looper 轮循.但对于其中细节似乎没有仔细思考过,抽上五分钟简要学习下! Lo ...

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

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

  5. 腾讯Android面试:Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么

    面试官: Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么 心理分析:该问题很难被考到,但是如果一旦问到,100%会回答不上来.开发者很难注意到一个主线程的四循环居然没有阻塞住主线程 ...

  6. Android切换到主线程

    Android切换到主线程 方法一: view.post(Runnable action) textView.post(new Runnable() { @Override public void r ...

  7. android如何阻塞主线程,Android-Android如何避免阻塞主线程

    Android的Handler和AsyncTask,可以避免阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的. AsyncTask,它使创建需要与用户界面交互的长时间运 ...

  8. android不能在主线程,android.os.NetworkOnMainThreadException 在4.0之后谷歌强制要求连接网络不能在主线程进行访问(示例代码)...

    谷歌在4.0系统以后就禁止在主线程中进行网络访问了,原因是: 主线程是负责UI的响应,如果在主线程进行网络访问,超过5秒的话就会引发强制关闭, 所以这种耗时的操作不能放在主线程里.放在子线程里,而子线 ...

  9. android网络请求不能放在主线程

    网络连接不能放在主线程 android 4.0 以上    网络连接不能放在主线程 4.0 以下 好像可以 在Android4.0以后,会发现,只要是写在主线程(就是Activity)中的HTTP请求 ...

最新文章

  1. 20+顶尖高校同时开打《王者荣耀》!实际上是一场科研battle,你能信?
  2. PathMatchingResourcePatternResolver通过适配符寻找符合条件的java类
  3. qt中用mysql获取所有的数据库、数据库中的表名
  4. 02-线性结构4 Pop Sequence
  5. Activity (项目实战:选择宝宝装备-UsersRegister)【Intent打开Activity、数据传递-回传、更新进度条】
  6. python运行出现数据错误_Python运行出错情况
  7. linux json 写sql注入,sql注入之AJAX(SQL Injection (AJAX/JSON/jQuery))
  8. 为什么老司机开车都不快?
  9. 文科辅修计算机科学,英属哥伦比亚大学专业详情.docx
  10. 基于触摸屏PLC的温度采集及简单控制
  11. Python状况:为什么PyPy是Python的未来?
  12. 关于win7快速启动栏以及显示桌面功能的还原
  13. android 画圆形图 获取圆形bitmap
  14. 为XYplorer添加右键菜单:“使用XYplorer打开”
  15. jq ajax简单使用方法
  16. 停车场寻车是怎么实现的?车库寻车有什么好办法?
  17. IntelliJ IDE
  18. Jmeter 之 Beanshell 用法
  19. Ubuntu下tar命令使用详解 .tar解压、.tar压缩
  20. BLAM源码解析(二)—— 从激光回调入手

热门文章

  1. 5G赋能智慧楼宇会后感
  2. Steam VR 出现重大错误或报错代码309解决途径之一
  3. sqluldr2 完美导出 ORACLE上亿条数据
  4. MySQL 根据指定某一天的时间查询数据
  5. WPS添加黑色编辑区域及段落
  6. 2018年计算机学校迎新标语,2018年开学迎新标语条幅
  7. 【180730】21点游戏源码
  8. 【Asp】在win10的IIS部署asp网站的注意事项!(避坑篇)
  9. 微信小程序-人脸照片入库
  10. FT232R驱动问题