美文网首页
ActivityThread、ApplicationThread

ActivityThread、ApplicationThread

作者: thomasyoungs | 来源:发表于2020-08-28 16:12 被阅读0次

    ActivityThread是什么

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

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

    Java程序初始类中的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");
        }
    
    }
    

    ApplicationThread是什么,有什么用?

    ApplicationThread是ActivityThread的内部类,也是一个Binder对象。在此处它是作为Activitythread和AMS通信的桥梁.

    private class ApplicationThread extends IApplicationThread.Stub {
         
            public final void schedulePauseActivity(IBinder token, boolean finished,
                       boolean userLeaving, int configChanges, boolean dontReport) {
                ......
            }
              public final void scheduleStopActivity(IBinder token, boolean showWindow,
                    int configChanges) {
                ......
            }
            public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                    ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
                    String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
                    PersistableBundle persistentState, List<ResultInfo> pendingResults,
                    List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
                    ProfilerInfo profilerInfo) {
                ......
            }
            ...... 
    }
    

    上述方法是用来启动activity的,除此外还有几种重要的方法,由此看来ApplicationThread的作用除了启动activity 和ams交互之外还用调用activity的生命周期方法,也就是我们看到的 几个activity生命周期方法。那么我们再看一下这些生命周期方法的调用过程。

    schedulePauseActivity()
    scheduleStopActivity()
    scheduleResumeActivity()
    scheduleSendResult()
    scheduleLaunchActivity()
    scheduleNewIntent()
    scheduleDestroyActivity()
    scheduleReceiver()
    scheduleCreateService()
    scheduleBindService()
    scheduleUnbindService()
    scheduleServiceArgs()
    scheduleStopService()
    bindApplication()
    scheduleConfigurationChanged()
    scheduleRegisteredReceiver()
    scheduleInstallProvider()
    

    ApplicationThread中的所有schedule方法内部都会调用一个sendMessage()而其实际要调用到activtyThread中的H的实例对象mH中,mH中定义了很多消息类型,下图是其handlerMessage方法,这也印章了我上边的所说的ApplicationThread的桥梁作用,ams直接通过binder调用,实际调用到activityThread中的方法 。

      private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) {
            if (DEBUG_MESSAGES) Slog.v(
                    TAG, "SCHEDULE " + mH.codeToString(what) + " arg1=" + arg1 + " arg2=" + arg2 +
                            "seq= " + seq);
            Message msg = Message.obtain();
            msg.what = what;
            SomeArgs args = SomeArgs.obtain();
            args.arg1 = obj;
            args.argi1 = arg1;
            args.argi2 = arg2;
            args.argi3 = seq;
            msg.obj = args;
            mH.sendMessage(msg);
        }
    
     private class H extends Handler {
          ……
            public void handleMessage(Message msg) {
                if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
                switch (msg.what) {
                    case LAUNCH_ACTIVITY: {
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                        final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
    
                        r.packageInfo = getPackageInfoNoCheck(
                                r.activityInfo.applicationInfo, r.compatInfo);
                        handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    } break;
                    case RELAUNCH_ACTIVITY: {
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
                        ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                        handleRelaunchActivity(r);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    } break;
                    case PAUSE_ACTIVITY: {
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                        SomeArgs args = (SomeArgs) msg.obj;
                        handlePauseActivity((IBinder) args.arg1, false,
                                (args.argi1 & USER_LEAVING) != 0, args.argi2,
                                (args.argi1 & DONT_REPORT) != 0, args.argi3);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    } break;
                    case PAUSE_ACTIVITY_FINISHING: {
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                        SomeArgs args = (SomeArgs) msg.obj;
                        handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,
                                args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    } break;
                    case STOP_ACTIVITY_SHOW: {
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
                        SomeArgs args = (SomeArgs) msg.obj;
                        handleStopActivity((IBinder) args.arg1, true, args.argi2, args.argi3);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    } break;
                    case STOP_ACTIVITY_HIDE: {
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
                        SomeArgs args = (SomeArgs) msg.obj;
                        handleStopActivity((IBinder) args.arg1, false, args.argi2, args.argi3);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    } break;
                    case SHOW_WINDOW:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
                        handleWindowVisibility((IBinder)msg.obj, true);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case HIDE_WINDOW:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
                        handleWindowVisibility((IBinder)msg.obj, false);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case RESUME_ACTIVITY:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
                        SomeArgs args = (SomeArgs) msg.obj;
                        handleResumeActivity((IBinder) args.arg1, true, args.argi1 != 0, true,
                                args.argi3, "RESUME_ACTIVITY");
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case SEND_RESULT:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
                        handleSendResult((ResultData)msg.obj);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case DESTROY_ACTIVITY:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
                        handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
                                msg.arg2, false);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case BIND_APPLICATION:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                        AppBindData data = (AppBindData)msg.obj;
                        handleBindApplication(data);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case EXIT_APPLICATION:
                        if (mInitialApplication != null) {
                            mInitialApplication.onTerminate();
                        }
                        Looper.myLooper().quit();
                        break;
                    case NEW_INTENT:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
                        handleNewIntent((NewIntentData)msg.obj);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case RECEIVER:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
                        handleReceiver((ReceiverData)msg.obj);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case CREATE_SERVICE:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
                        handleCreateService((CreateServiceData)msg.obj);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case BIND_SERVICE:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
                        handleBindService((BindServiceData)msg.obj);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case UNBIND_SERVICE:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
                        handleUnbindService((BindServiceData)msg.obj);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case SERVICE_ARGS:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
                        handleServiceArgs((ServiceArgsData)msg.obj);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case STOP_SERVICE:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
                        handleStopService((IBinder)msg.obj);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
            
                 
                }
                Object obj = msg.obj;
                if (obj instanceof SomeArgs) {
                    ((SomeArgs) obj).recycle();
                }
                if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
            }
        }
    
    
     private void handleDestroyActivity(IBinder token, boolean finishing,
                int configChanges, boolean getNonConfigInstance) {
            ActivityClientRecord r = performDestroyActivity(token, finishing,
                    configChanges, getNonConfigInstance);
            if (r != null) {
                cleanUpPendingRemoveWindows(r, finishing);
                WindowManager wm = r.activity.getWindowManager();
                View v = r.activity.mDecor;
                if (v != null) {
                    if (r.activity.mVisibleFromServer) {
                        mNumVisibleActivities--;
                    }
                    IBinder wtoken = v.getWindowToken();
                    if (r.activity.mWindowAdded) {
                        if (r.mPreserveWindow) {
                            // Hold off on removing this until the new activity's
                            // window is being added.
                            r.mPendingRemoveWindow = r.window;
                            r.mPendingRemoveWindowManager = wm;
                            // We can only keep the part of the view hierarchy that we control,
                            // everything else must be removed, because it might not be able to
                            // behave properly when activity is relaunching.
                            r.window.clearContentView();
                        } else {
                            wm.removeViewImmediate(v);
                        }
                    }
                    if (wtoken != null && r.mPendingRemoveWindow == null) {
                        WindowManagerGlobal.getInstance().closeAll(wtoken,
                                r.activity.getClass().getName(), "Activity");
                    } else if (r.mPendingRemoveWindow != null) {
                        // We're preserving only one window, others should be closed so app views
                        // will be detached before the final tear down. It should be done now because
                        // some components (e.g. WebView) rely on detach callbacks to perform receiver
                        // unregister and other cleanup.
                        WindowManagerGlobal.getInstance().closeAllExceptView(token, v,
                                r.activity.getClass().getName(), "Activity");
                    }
                    r.activity.mDecor = null;
                }
                if (r.mPendingRemoveWindow == null) {
                    // If we are delaying the removal of the activity window, then
                    // we can't clean up all windows here.  Note that we can't do
                    // so later either, which means any windows that aren't closed
                    // by the app will leak.  Well we try to warning them a lot
                    // about leaking windows, because that is a bug, so if they are
                    // using this recreate facility then they get to live with leaks.
                    WindowManagerGlobal.getInstance().closeAll(token,
                            r.activity.getClass().getName(), "Activity");
                }
    
                // Mocked out contexts won't be participating in the normal
                // process lifecycle, but if we're running with a proper
                // ApplicationContext we need to have it tear down things
                // cleanly.
                Context c = r.activity.getBaseContext();
                if (c instanceof ContextImpl) {
                    ((ContextImpl) c).scheduleFinalCleanup(
                            r.activity.getClass().getName(), "Activity");
                }
            }
            if (finishing) {
                try {
                    ActivityManager.getService().activityDestroyed(token);
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
            }
            mSomeActivitiesChanged = true;
        }
    

    ActivityClientRecord 上述代码太多我删掉了好多不熟悉的,我们看到了STOP_SERVICE,DESTROY_ACTIVITY,所以继续用我们比较熟悉的DESTROY_ACTIVITY为例进行分析。于是又抛出一个新的概念ActivityClientRecord(感觉我是写不完了。。。)因为上述代码已经拿到了activity window等我们熟知的对象,所以里边的方法就不继续深入讨论,下次有时间继续撸ActivityClientRecord 在activity启动中是如何发挥作用的。

    static final class ActivityClientRecord {
            IBinder token;
            int ident;
            Intent intent;
            String referrer;
            IVoiceInteractor voiceInteractor;
            Bundle state;
            PersistableBundle persistentState;
            Activity activity;
            Window window;
            Activity parent;
            String embeddedID;
            Activity.NonConfigurationInstances lastNonConfigurationInstances;
            ……
            ActivityClientRecord nextIdle;
            ProfilerInfo profilerInfo;
            ActivityInfo activityInfo;
            CompatibilityInfo compatInfo;
            LoadedApk packageInfo;
    
    
            Window mPendingRemoveWindow;
            WindowManager mPendingRemoveWindowManager;
            boolean mPreserveWindow;
    
            // Set for relaunch requests, indicates the order number of the relaunch operation, so it
            // can be compared with other lifecycle operations.
            int relaunchSeq = 0;
    
            // Can only be accessed from the UI thread. This represents the latest processed message
            // that is related to lifecycle events/
            int lastProcessedSeq = 0;
    
            ActivityClientRecord() {
                parent = null;
                embeddedID = null;
                paused = false;
                stopped = false;
                hideForNow = false;
                nextIdle = null;
                configCallback = (Configuration overrideConfig, int newDisplayId) -> {
                    if (activity == null) {
                        throw new IllegalStateException(
                                "Received config update for non-existing activity");
                    }
                    activity.mMainThread.handleActivityConfigurationChanged(
                            new ActivityConfigChangeData(token, overrideConfig), newDisplayId);
                };
            }
          ……
        }
    

    相关文章

      网友评论

          本文标题:ActivityThread、ApplicationThread

          本文链接:https://www.haomeiwen.com/subject/cyvlsktx.html