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

登山则情满于山,观海则意溢于海。这篇文章主要讲述Android ActivityThread(主线程或UI线程)简介相关的知识,希望能为你提供帮助。
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派生类的应用程序中,它包含如下线程:

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

文章图片

    main线程stack如下:
 
[java]  view plain  copy    
Android ActivityThread(主线程或UI线程)简介

文章图片
Android ActivityThread(主线程或UI线程)简介

文章图片
  1. at  android.os.MessageQueue.nativePollOnce(Native  Method)           
  2. at  android.os.MessageQueue.next(MessageQueue.java:118)       
  3. at  android.os.Looper.loop(Looper.java:118)       
  4.    
  5. at  android.app.ActivityThread.main(ActivityThread.java:4424)        //  Java  main入口函数   
  6.    
  7. at  java.lang.reflect.Method.invokeNative(Native  Method)     
  8. at  java.lang.reflect.Method.invoke(Method.java:511)     
  9. at  com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)       
  10. at  com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)     
  11. at  dalvik.system.NativeStart.main(Native  Method)           

      JDWP线程stack如下:
 
[java]  view plain  copy    
Android ActivityThread(主线程或UI线程)简介

文章图片
Android ActivityThread(主线程或UI线程)简介

文章图片
  1. at  org.apache.harmony.dalvik.ddmc.DdmVmInternal.getStackTraceById(Native  Method)           
  2. at  android.ddm.DdmHandleThread.handleSTKL(DdmHandleThread.java:131)     
  3. at  android.ddm.DdmHandleThread.handleChunk(DdmHandleThread.java:77)     
  4. at  org.apache.harmony.dalvik.ddmc.DdmServer.dispatch(DdmServer.java:171)           
  5. at  dalvik.system.NativeStart.run(Native  Method)     
 
3. IApplicationThread关系图
Android ActivityThread(主线程或UI线程)简介

文章图片

 
4. ActivityThread类    ActivityThread类即代表Application主线程。
4.1 类中关键信息【Android ActivityThread(主线程或UI线程)简介】 
[java]  view plain  copy    
Android ActivityThread(主线程或UI线程)简介

文章图片
Android ActivityThread(主线程或UI线程)简介

文章图片
  1. /** 
  2.   *  This  manages  the  execution  of  the  main  thread  in  an 
  3.   *  application  process,  scheduling  and  executing  activities, 
  4.   *  broadcasts,  and  other  operations  on  it  as  the  activity 
  5.   *  manager  requests. 
  6.   * 
  7.   *  {@hide} 
  8.   */   
  9. public  final  class  ActivityThread  {   
  10.    
  11.         static  ContextImpl  mSystemContext  =  null;    
  12.    
  13.         static  IPackageManager  sPackageManager;    
  14.            
  15.         //  创建ApplicationThread实例,以接收AMS指令并执行   
  16.         final  ApplicationThread  mAppThread  =  new  ApplicationThread();    
  17.    
  18.         final  Looper  mLooper  =  Looper.myLooper();    
  19.    
  20.         final  H  mH  =  new  H();    
  21.    
  22.         final  HashMap< IBinder,  ActivityClientRecord>   mActivities   
  23.                         =  new  HashMap< IBinder,  ActivityClientRecord> ();    
  24.            
  25.         //  List  of  new  activities  (via  ActivityRecord.nextIdle)  that  should   
  26.         //  be  reported  when  next  we  idle.   
  27.         ActivityClientRecord  mNewActivities  =  null;    
  28.            
  29.         //  Number  of  activities  that  are  currently  visible  on-screen.   
  30.         int  mNumVisibleActivities  =  0;    
  31.            
  32.         final  HashMap< IBinder,  Service>   mServices   
  33.                         =  new  HashMap< IBinder,  Service> ();    
  34.            
  35.         Application  mInitialApplication;    
  36.    
  37.         final  ArrayList< Application>   mAllApplications   
  38.                         =  new  ArrayList< Application> ();    
  39.    
  40.         static  final  ThreadLocal< ActivityThread>   sThreadLocal  =  new  ThreadLocal< ActivityThread> ();    
  41.         Instrumentation  mInstrumentation;    
  42.    
  43.         static  Handler  sMainThreadHandler;     //  set  once  in  main()   
  44.    
  45.         static  final  class  ActivityClientRecord  {   
  46.                 IBinder  token;    
  47.                 int  ident;    
  48.                 Intent  intent;    
  49.                 Bundle  state;    
  50.                 Activity  activity;    
  51.                 Window  window;    
  52.                 Activity  parent;    
  53.                 String  embeddedID;    
  54.                 Activity.NonConfigurationInstances  lastNonConfigurationInstances;    
  55.                 boolean  paused;    
  56.                 boolean  stopped;    
  57.                 boolean  hideForNow;    
  58.                 Configuration  newConfig;    
  59.                 Configuration  createdConfig;    
  60.                 ActivityClientRecord  nextIdle;    
  61.    
  62.                 String  profileFile;    
  63.                 ParcelFileDescriptor  profileFd;    
  64.                 boolean  autoStopProfiler;    
  65.    
  66.                 ActivityInfo  activityInfo;    
  67.                 CompatibilityInfo  compatInfo;    
  68.                 LoadedApk  packageInfo;   //包信息,通过调用ActivityThread.getPapckageInfo而获得   
  69.    
  70.                 List< ResultInfo>   pendingResults;    
  71.                 List< Intent>   pendingIntents;    
  72.    
  73.                 boolean  startsNotResumed;    
  74.                 boolean  isForward;    
  75.                 int  pendingConfigChanges;    
  76.                 boolean  onlyLocalRequest;    
  77.    
  78.                 View  mPendingRemoveWindow;    
  79.                 WindowManager  mPendingRemoveWindowManager;    
  80.    
  81.                 ...   
  82.         }   
  83.    
  84.    
  85.         private  class  ApplicationThread  extends  ApplicationThreadNative  {   
  86.    
  87.                 private  void  updatePendingConfiguration(Configuration  config)  {   
  88.                         synchronized  (mPackages)  {   
  89.                                 if  (mPendingConfiguration  ==  null  ||   
  90.                                                 mPendingConfiguration.isOtherSeqNewer(config))  {   
  91.                                         mPendingConfiguration  =  config;    
  92.                                 }   
  93.                         }   
  94.                 }   
  95.    
  96.                 public  final  void  schedulePauseActivity(IBinder  token,  boolean  finished,   
  97.                                 boolean  userLeaving,  int  configChanges)  {   
  98.                         queueOrSendMessage(   
  99.                                         finished  ?  H.PAUSE_ACTIVITY_FINISHING  :  H.PAUSE_ACTIVITY,   
  100.                                         token,   
  101.                                         (userLeaving  ?  1  :  0),   
  102.                                         configChanges);    
  103.                 }   
  104.    
  105.                 //  we  use  token  to  identify  this  activity  without  having  to  send  the   
  106.                 //  activity  itself  back  to  the  activity  manager.  (matters  more  with  ipc)   
  107.                 public  final  void  scheduleLaunchActivity(Intent  intent,  IBinder  token,  int  ident,   
  108.                                 ActivityInfo  info,  Configuration  curConfig,  CompatibilityInfo  compatInfo,   
  109.                                 Bundle  state,  List< ResultInfo>   pendingResults,   
  110.                                 List< Intent>   pendingNewIntents,  boolean  notResumed,  boolean  isForward,   
  111.                                 String  profileName,  ParcelFileDescriptor  profileFd,  boolean  autoStopProfiler)  {   
  112.                         ActivityClientRecord  r  =  new  ActivityClientRecord();    
  113.    
  114.                         r.token  =  token;    
  115.                         r.ident  =  ident;    
  116.                         r.intent  =  intent;    
  117.                         r.activityInfo  =  info;    
  118.                         r.compatInfo  =  compatInfo;    
  119.                         r.state  =  state;    
  120.    
  121.                         r.pendingResults  =  pendingResults;    
  122.                         r.pendingIntents  =  pendingNewIntents;    
  123.    
  124.                         r.startsNotResumed  =  notResumed;    
  125.                         r.isForward  =  isForward;    
  126.    
  127.                         r.profileFile  =  profileName;    
  128.                         r.profileFd  =  profileFd;    
  129.                         r.autoStopProfiler  =  autoStopProfiler;    
  130.    
  131.                         updatePendingConfiguration(curConfig);    
  132.    
  133.                         queueOrSendMessage(H.LAUNCH_ACTIVITY,  r);    
  134.                 }   
  135.    
  136.                 ...   
  137.         }   
  138.    
  139.         private  class  H  extends  Handler  {   
  140.    
  141.                 public  void  handleMessage(Message  msg)  {   
  142.                         if  (DEBUG_MESSAGES)  Slog.v(TAG,  "> > >   handling:  "  +  codeToString(msg.what));    
  143.                         switch  (msg.what)  {   
  144.                                 case  LAUNCH_ACTIVITY:  {   
  145.                                         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,  "activityStart");    
  146.                                         ActivityClientRecord  r  =  (ActivityClientRecord)msg.obj;    
  147.    
  148.                                         r.packageInfo  =  getPackageInfoNoCheck(   
  149.                                                         r.activityInfo.applicationInfo,  r.compatInfo);    
  150.                                         handleLaunchActivity(r,  null);    
  151.                                         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);    
  152.                                 }  break;    
  153.                                 ...   
  154.                         }   
  155.                         if  (DEBUG_MESSAGES)  Slog.v(TAG,  "< < <   done:  "  +  codeToString(msg.what));    
  156.                 }   
  157.                  
  158.                 ...   
  159.         }   
  160.    
  161.         public  static  ActivityThread  currentActivityThread()  {   
  162.                 return  sThreadLocal.get();    
  163.         }   
  164.    
  165.      
  166.         public  static  void  main(String[]  args)  {   
  167.                 SamplingProfilerIntegration.start();    
  168.    
  169.                 //  CloseGuard  defaults  to  true  and  can  be  quite  spammy.    We   
  170.                 //  disable  it  here,  but  selectively  enable  it  later  (via   
  171.                 //  StrictMode)  on  debug  builds,  but  using  DropBox,  not  logs.   
  172.                 CloseGuard.setEnabled(false);    
  173.    
  174.                 Environment.initForCurrentUser();    
  175.    
  176.                 //  Set  the  reporter  for  event  logging  in  libcore   
  177.                 EventLogger.setReporter(new  EventLoggingReporter());    
  178.    
  179.                 Process.setArgV0("< pre-initialized> ");    
  180.    
  181.                 Looper.prepareMainLooper();    
  182.    
  183.                 //  创建ActivityThread实例   
  184.                 ActivityThread  thread  =  new  ActivityThread();    
  185.                 thread.attach(false);    
  186.    
  187.                 if  (sMainThreadHandler  ==  null)  {   
  188.                         sMainThreadHandler  =  thread.getHandler();    
  189.                 }   
  190.    
  191.                 AsyncTask.init();    
  192.    
  193.                 if  (false)  {   
  194.                         Looper.myLooper().setMessageLogging(new   
  195.                                         LogPrinter(Log.DEBUG,  "ActivityThread"));    
  196.                 }   
  197.    
  198.                 Looper.loop();    
  199.    
  200.                 throw  new  RuntimeException("Main  thread  loop  unexpectedly  exited");    
  201.         }   
  202. }   



4.2 家族图谱
Android ActivityThread(主线程或UI线程)简介

文章图片

 
4.3 ActivityThread内部类
Android ActivityThread(主线程或UI线程)简介

文章图片

 
4.4 ActivityThread工作流程




    推荐阅读