zoukankan      html  css  js  c++  java
  • android主线程ActivityThread

    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: {
                        //...启动一个Activity
                        handleLaunchActivity(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);
        }
        @Override
        public 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 Binder
            implements 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对象进行跨进程调用。

  • 相关阅读:
    php删除最后一个字符
    git删除远程分支
    lsof命令
    高效率的全组合算法(Java版实现)
    Java类变量和成员变量初始化过程
    pig命令行快捷键
    java的HashCode方法
    待学习
    长连接和短连接
    Hadoop学习之SecondaryNameNode
  • 原文地址:https://www.cnblogs.com/mingfeng002/p/10323668.html
Copyright © 2011-2022 走看看