• ActivityThread


    1. ActivityThread 功能
        
    它管理应用进程的主线程的执行(相当于普通Java程序的main入口函数),并根据AMS的要求(通过IApplicationThread接口,AMS为Client、ActivityThread.ApplicationThread为Server)负责调度和执行activities、broadcasts和其它操作。
        
    在Android系统中,在默认情况下,一个应用程序内的各个组件(如Activity、BroadcastReceiver、Service)都会在同一个进程(Process)里执行,且由此进程的【主线程】负责执行。
        
    在Android系统中,如果有特别指定(通过android:process),也可以让特定组件在不同的进程中运行。无论组件在哪一个进程中运行,默认情况下,他们都由此进程的【主线程】负责执行。
        
    【主线程】既要处理Activity组件的UI事件,又要处理Service后台服务工作,通常会忙不过来。为了解决此问题,主线程可以创建多个子线程来处理后台服务工作,而本身专心处理UI画面的事件。
         
    【主线程】的主要责任:
           
    •快速处理UI事件。而且只有它才处理UI事件, 其它线程还不能存取UI画面上的对象(如TextView等),此时, 主线程就叫做UI线程。基本上,Android希望UI线程能根据用户的要求做出快速响应,如果UI线程花太多时间处理后台的工作,当UI事件发生时,让用户等待时间超过5秒而未处理,Android系统就会给用户显示ANR提示信息。
    
    只有UI线程才能执行View派生类的onDraw()函数。
          
    • 快速处理Broadcast消息。【主线程】除了处理UI事件之外,还要处理Broadcast消息。所以在BroadcastReceiver的onReceive()函数中,不宜占用太长的时间,否则导致【主线程】无法处理其它的Broadcast消息或UI事件。如果占用时间超过10秒, Android系统就会给用户显示ANR提示信息。
          
      注意事项:
          
    •尽量避免让【主线程】执行耗时的操作,让它能快速处理UI事件和Broadcast消息。
    •BroadcastReceiver的子类都是无状态的,即每次启动时,才会创建其对象,然后调用它的onReceive()函数,当执行完onReceive()函数时,就立即删除此对象。由于每次调用其函数时,会重新创建一个新的对象,所以对象里的属性值,是无法让各函数所共享。   
    
    1.1 Thread与SurfaceView
    
    View组件由UI线程(主线程)所执行。如果需要迅速更新UI画面或UI画图需要较长时间,则需要使用SurfaceView。它可由后台线程(background thread)来执行,而View只能由UI(主)线程执行。SurfaceView内有高效的rendering机制,可以让后台线程快速刷新Surface的内容。
          View ---> UI(主)线程
          SurfaceView ---> 后台线程   
    
    2. Android应用程序主线程stack
        在一个只有Activity派生类的应用程序中,它包含如下线程:
    
    
    
    main 线程 stack 如下:
    
    at android.os.MessageQueue.nativePollOnce(Native Method)      
    at android.os.MessageQueue.next(MessageQueue.java:118)    
    at android.os.Looper.loop(Looper.java:118)    
      
    at android.app.ActivityThread.main(ActivityThread.java:4424)    // Java main入口函数  
      
    at java.lang.reflect.Method.invokeNative(Native Method)   
    at java.lang.reflect.Method.invoke(Method.java:511)   
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)    
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)   
    at dalvik.system.NativeStart.main(Native Method)      
    
    JDWP线程stack如下:
    
    at org.apache.harmony.dalvik.ddmc.DdmVmInternal.getStackTraceById(Native Method)      
    at android.ddm.DdmHandleThread.handleSTKL(DdmHandleThread.java:131)   
    at android.ddm.DdmHandleThread.handleChunk(DdmHandleThread.java:77)   
    at org.apache.harmony.dalvik.ddmc.DdmServer.dispatch(DdmServer.java:171)      
    at dalvik.system.NativeStart.run(Native Method)   
    
    3. IApplicationThread 关系图
    
    
    
    4. ActivityThread类
       
    ActivityThread 类即代表 Application 主线程。
    
    4.1 类中关键信息
    
    public final class ActivityThread {
    
        static ContextImpl mSystemContext = null;
    
        static IPackageManager sPackageManager;
    
        // 创建ApplicationThread实例,以接收AMS指令并执行  
        final ApplicationThread mAppThread = new ApplicationThread();
    
        final Looper mLooper = Looper.myLooper();
    
        final H mH = new H();
    
        final HashMap<IBinder, ActivityClientRecord> mActivities
                = new HashMap<IBinder, ActivityClientRecord>();
    
        // List of new activities (via ActivityRecord.nextIdle) that should  
        // be reported when next we idle.  
        ActivityClientRecord mNewActivities = null;
    
        // Number of activities that are currently visible on-screen.  
        int mNumVisibleActivities = 0;
    
        final HashMap<IBinder, Service> mServices
                = new HashMap<IBinder, Service>();
    
        Application mInitialApplication;
    
        final ArrayList<Application> mAllApplications
                = new ArrayList<Application>();
    
        static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal<ActivityThread>();
        Instrumentation mInstrumentation;
    
        static Handler sMainThreadHandler;  // set once in main()  
    
        static final class ActivityClientRecord {
            IBinder token;
            int ident;
            Intent intent;
            Bundle state;
            Activity activity;
            Window window;
            Activity parent;
            String embeddedID;
            Activity.NonConfigurationInstances lastNonConfigurationInstances;
            boolean paused;
            boolean stopped;
            boolean hideForNow;
            Configuration newConfig;
            Configuration createdConfig;
            ActivityClientRecord nextIdle;
    
            String profileFile;
            ParcelFileDescriptor profileFd;
            boolean autoStopProfiler;
    
            ActivityInfo activityInfo;
            CompatibilityInfo compatInfo;
            LoadedApk packageInfo; //包信息,通过调用ActivityThread.getPapckageInfo而获得  
    
            List<ResultInfo> pendingResults;
            List<Intent> pendingIntents;
    
            boolean startsNotResumed;
            boolean isForward;
            int pendingConfigChanges;
            boolean onlyLocalRequest;
    
            View mPendingRemoveWindow;
            WindowManager mPendingRemoveWindowManager;
    
            ...
        }
    
    
        private class ApplicationThread extends ApplicationThreadNative {
    
            private void updatePendingConfiguration(Configuration config) {
                synchronized (mPackages) {
                    if (mPendingConfiguration == null ||
                            mPendingConfiguration.isOtherSeqNewer(config)) {
                        mPendingConfiguration = config;
                    }
                }
            }
    
            public final void schedulePauseActivity(IBinder token, boolean finished,
                                                    boolean userLeaving, int configChanges) {
                queueOrSendMessage(
                        finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                        token,
                        (userLeaving ? 1 : 0),
                        configChanges);
            }
    
            // we use token to identify this activity without having to send the  
            // activity itself back to the activity manager. (matters more with ipc)  
            public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                                                     ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
                                                     Bundle state, List<ResultInfo> pendingResults,
                                                     List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
                                                     String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
                ActivityClientRecord r = new ActivityClientRecord();
    
                r.token = token;
                r.ident = ident;
                r.intent = intent;
                r.activityInfo = info;
                r.compatInfo = compatInfo;
                r.state = state;
    
                r.pendingResults = pendingResults;
                r.pendingIntents = pendingNewIntents;
    
                r.startsNotResumed = notResumed;
                r.isForward = isForward;
    
                r.profileFile = profileName;
                r.profileFd = profileFd;
                r.autoStopProfiler = autoStopProfiler;
    
                updatePendingConfiguration(curConfig);
    
                queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
            }
    
            ...
        }  
    
    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");
                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;
    
                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                ...
            }
            if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
        }
    
        ...
    }
    
        public static ActivityThread currentActivityThread() {
            return sThreadLocal.get();
        }
    
    
        public static void main(String[] args) {
            SamplingProfilerIntegration.start();
    
            // CloseGuard defaults to true and can be quite spammy.  We  
            // disable it here, but selectively enable it later (via  
            // StrictMode) on debug builds, but using DropBox, not logs.  
            CloseGuard.setEnabled(false);
    
            Environment.initForCurrentUser();
    
            // Set the reporter for event logging in libcore  
            EventLogger.setReporter(new EventLoggingReporter());
    
            Process.setArgV0("<pre-initialized>");
    
            Looper.prepareMainLooper();
    
            // 创建ActivityThread实例  
            ActivityThread thread = new ActivityThread();
            thread.attach(false);
    
            if (sMainThreadHandler == null) {
                sMainThreadHandler = thread.getHandler();
            }
    
            AsyncTask.init();
    
            if (false) {
                Looper.myLooper().setMessageLogging(new
                        LogPrinter(Log.DEBUG, "ActivityThread"));
            }
    
            Looper.loop();
    
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
    }
    
    4.2 家族图谱
  • 相关阅读:
    Cmder安装和设置
    php7.x版本的新特性
    【Luogu】P4916 [MtOI2018]魔力环 题解
    Codeforces 1530E Minimax 题解
    昭阳E42-80 屏幕不亮,风扇狂转
    iPad宽高像素值
    关于UIView的autoresizingMask属性的研究
    判断单链表中是否存在环及查找环的入口点
    网络编程
    事件响应者链的工作原理
  • 原文地址:https://www.cnblogs.com/zx-blog/p/11835921.html
Copyright © 2020-2023  润新知