Activity的启动过程

来源:互联网 发布:淘宝实拍保护入口 编辑:程序博客网 时间:2024/06/05 08:47

ActivityThread类main方法是一个Andorid应用程序的入口。

ActivityThread类只是一个普通的类,他并是一个Thread。

下面就从ActivityThread的main方法入手

[java] view plaincopy
  1. public static void main(String[] args) {  
  2.        SamplingProfilerIntegration.start();  
  3.   
  4.        // CloseGuard defaults to true and can be quite spammy.  We  
  5.        // disable it here, but selectively enable it later (via  
  6.        // StrictMode) on debug builds, but using DropBox, not logs.  
  7.        CloseGuard.setEnabled(false);  
  8.   
  9.        Process.setArgV0("<pre-initialized>");  
  10.   
  11.        //此方法其实就是创建UI线程相关的Looper实例  
  12.        Looper.prepareMainLooper();  
  13.        if (sMainThreadHandler == null) {  
  14.            sMainThreadHandler = new Handler();  
  15.        }  
  16.   
  17.        //创建一个ActivityThread对象  
  18.        ActivityThread thread = new ActivityThread();  
  19.         
  20.        //调用ActivityThread的attach(Boolean)方法,与AMS进行通信,  
  21.        thread.attach(false);  
  22.   
  23.        if (false) {  
  24.            Looper.myLooper().setMessageLogging(new  
  25.                    LogPrinter(Log.DEBUG, "ActivityThread"));  
  26.        }  
  27.   
  28.        //让Looper去轮询消息队列  
  29.        Looper.loop();  
  30.   
  31.        throw new RuntimeException("Main thread loop unexpectedly exited");  
  32.    }  

ThreadActivity就是通过
[java] view plaincopy
  1. thread.attach(false);  

这个方法来实现与Ams进行交互,当然attach中还会调用很多其他的类和方法。下面看

[java] view plaincopy
  1.     private void attach(boolean system) {  
  2.         sThreadLocal.set(this);  
  3.         mSystemThread = system;  
  4.         if (!system) {  
  5.             ViewRootImpl.addFirstDrawHandler(new Runnable() {  
  6.                 public void run() {  
  7.                     ensureJitEnabled();  
  8.                 }  
  9.             });  
  10.             android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");  
  11.               
  12.             RuntimeInit.setApplicationObject(mAppThread.asBinder());  
  13.               
  14.             /* 
  15.              *ActivityManagerNative是ActivityManagerService的代理类, 
  16. <span style="white-space:pre">            </span> *此类是Binder的子类,用来实现Activity与ActivityManagerService之间的交互   
  17.              *所以说与AMS的交互是通过Binder机制来实现的 
  18.              *  
  19.              */  
  20.             IActivityManager mgr = ActivityManagerNative.getDefault();  
  21.              
  22.             try {  
  23.             <span style="white-space:pre">  </span>  
  24.             <span style="white-space:pre">  </span>//向AMSf发送消息。  
  25.                 mgr.attachApplication(mAppThread);  
  26.              
  27.             } catch (RemoteException ex) {  
  28.                 // Ignore  
  29.             }  
  30.         } else {  
  31.             // Don't set application object here -- if the system crashes,  
  32.             // we can't display an alert, we just want to die die die.  
  33.             android.ddm.DdmHandleAppName.setAppName("system_process");  
  34.             try {  
  35.   
  36.   
  37.             <span style="white-space:pre">  </span>/*Instrumentation的作用  
  38.             <span style="white-space:pre">  </span> * 1.调用Activity的相关周期方法 
  39.             <span style="white-space:pre">  </span> * 2.创建application 
  40.             <span style="white-space:pre">  </span> * 3.启动Activity 
  41.             <span style="white-space:pre">  </span> */  
  42.                 mInstrumentation = new Instrumentation();  
  43.                   
  44.                 //下面的代码就是创建一个Application实例对象,并调用它的onCreate()  
  45.                 ContextImpl context = new ContextImpl();  
  46.                 context.init(getSystemContext().mPackageInfo, nullthis);  
  47.                 Application app = Instrumentation.newApplication(Application.class, context);  
  48.                 mAllApplications.add(app);  
  49.                 mInitialApplication = app;  
  50.                 app.onCreate();  
  51.             } catch (Exception e) {  
  52.                 throw new RuntimeException(  
  53.                         "Unable to instantiate Application():" + e.toString(), e);  
  54.             }  
  55.         }  
  56.           
  57.         ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {  
  58.             public void onConfigurationChanged(Configuration newConfig) {  
  59.                 synchronized (mPackages) {  
  60.                     // We need to apply this change to the resources  
  61.                     // immediately, because upon returning the view  
  62.                     // hierarchy will be informed about it.  
  63.                     if (applyConfigurationToResourcesLocked(newConfig, null)) {  
  64.                         // This actually changed the resources!  Tell  
  65.                         // everyone about it.  
  66.                         if (mPendingConfiguration == null ||  
  67.                                 mPendingConfiguration.isOtherSeqNewer(newConfig)) {  
  68.                             mPendingConfiguration = newConfig;  
  69.                               
  70.                             queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);  
  71.                         }  
  72.                     }  
  73.                 }  
  74.             }  
  75.             public void onLowMemory() {  
  76.             }  
  77.             public void onTrimMemory(int level) {  
  78.             }  
  79.         });  
  80.     }  
这方法其实就是在通过binder在向AMS发送请求,他的参数是ApplicationThread

[java] view plaincopy
  1. final ApplicationThread mAppThread = new ApplicationThread();  
ActivityThread的一个字段,ActivityThread 对象一创建,就会创建此类的实例对象,

Ams在接到请求后就会给ActivityThread反馈。反馈回来的消息将传递给

H类来处理,H类是Handler的子类。当H收到的是一个开启Activity的消息时会执行以下代码


[java] view plaincopy
  1. case LAUNCH_ACTIVITY: {  
  2.                     ActivityClientRecord r = (ActivityClientRecord)msg.obj;  
  3.   
  4.   
  5.                     r.packageInfo = getPackageInfoNoCheck(  
  6.                             r.activityInfo.applicationInfo, r.compatInfo);  
  7.                     handleLaunchActivity(r, null);  
  8.                 } break;  



首先来了解几个类

ActivityClientRecord类

此类是对一个客户端的Activity的描述,只是做一个记录。每一个Activity被创建是都会有一个ActivityClientRecord与之对应,

此类中还包含一个ActivityInfo成员,ActivityInfo主要描述了Activity的权限信息,粘合性。


ActivityRecord类:主要用于AMS中记录Activity,与客户端中的ActivityClientRecord类相对应。

下面看


[java] view plaincopy
  1. private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {  
  2.     // If we are getting ready to gc after going to the background, well  
  3.     // we are back active so skip it.  
  4.     unscheduleGcIdler();  
  5.   
  6.     if (r.profileFd != null) {  
  7.         mProfiler.setProfiler(r.profileFile, r.profileFd);  
  8.         mProfiler.startProfiling();  
  9.         mProfiler.autoStopProfiler = r.autoStopProfiler;  
  10.     }  
  11.   
  12.     // Make sure we are running with the most recent config.  
  13.     handleConfigurationChanged(nullnull);  
  14.   
  15.     if (localLOGV) Slog.v(  
  16.         TAG, "Handling launch of " + r);  
  17.     Activity a = performLaunchActivity(r, customIntent);  
  18.   
  19.     if (a != null) {  
  20.         r.createdConfig = new Configuration(mConfiguration);  
  21.         Bundle oldState = r.state;  
  22.         handleResumeActivity(r.token, false, r.isForward);  
  23.   
  24.         if (!r.activity.mFinished && r.startsNotResumed) {  
  25.             // The activity manager actually wants this one to start out  
  26.             // paused, because it needs to be visible but isn't in the  
  27.             // foreground.  We accomplish this by going through the  
  28.             // normal startup (because activities expect to go through  
  29.             // onResume() the first time they run, before their window  
  30.             // is displayed), and then pausing it.  However, in this case  
  31.             // we do -not- need to do the full pause cycle (of freezing  
  32.             // and such) because the activity manager assumes it can just  
  33.             // retain the current state it has.  
  34.             try {  
  35.                 r.activity.mCalled = false;  
  36.                 mInstrumentation.callActivityOnPause(r.activity);  
  37.                 // We need to keep around the original state, in case  
  38.                 // we need to be created again.  
  39.                 r.state = oldState;  
  40.                 if (!r.activity.mCalled) {  
  41.                     throw new SuperNotCalledException(  
  42.                         "Activity " + r.intent.getComponent().toShortString() +  
  43.                         " did not call through to super.onPause()");  
  44.                 }  
  45.   
  46.             } catch (SuperNotCalledException e) {  
  47.                 throw e;  
  48.   
  49.             } catch (Exception e) {  
  50.                 if (!mInstrumentation.onException(r.activity, e)) {  
  51.                     throw new RuntimeException(  
  52.                             "Unable to pause activity "  
  53.                             + r.intent.getComponent().toShortString()  
  54.                             + ": " + e.toString(), e);  
  55.                 }  
  56.             }  
  57.             r.paused = true;  
  58.         }  
  59.     } else {  
  60.         // If there was an error, for any reason, tell the activity  
  61.         // manager to stop us.  
  62.         try {  
  63.             ActivityManagerNative.getDefault()  
  64.                 .finishActivity(r.token, Activity.RESULT_CANCELED, null);  
  65.         } catch (RemoteException ex) {  
  66.             // Ignore  
  67.         }  
  68.     }  
  69. }  


handleLaunchActivity方法首先要创建Activity

[java] view plaincopy
  1. Activity a = performLaunchActivity(r, customIntent);  
再看

[java] view plaincopy
  1.     private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {  
  2.         // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");  
  3.   
  4.   
  5.         ActivityInfo aInfo = r.activityInfo;  
  6.         if (r.packageInfo == null) {  
  7.             r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,  
  8.                     Context.CONTEXT_INCLUDE_CODE);  
  9.         }  
  10.   
  11.   
  12.         ComponentName component = r.intent.getComponent();  
  13.         if (component == null) {  
  14.             component = r.intent.resolveActivity(  
  15.                 mInitialApplication.getPackageManager());  
  16.             r.intent.setComponent(component);  
  17.         }  
  18.   
  19.   
  20.         if (r.activityInfo.targetActivity != null) {  
  21.             component = new ComponentName(r.activityInfo.packageName,  
  22.                     r.activityInfo.targetActivity);  
  23.         }  
  24.   
  25.   
  26.         Activity activity = null;  
  27.         try {  
  28.        /* 
  29.         * 此代码其实就是通过反射创建一个Activity的实例对象,但他此时仅仅只是一个普通的对象 
  30.         */  
  31.             java.lang.ClassLoader cl = r.packageInfo.getClassLoader();  
  32.             activity = mInstrumentation.newActivity(  
  33.                     cl, component.getClassName(), r.intent);  
  34.             StrictMode.incrementExpectedActivityCount(activity.getClass());  
  35.             r.intent.setExtrasClassLoader(cl);  
  36.             if (r.state != null) {  
  37.                 r.state.setClassLoader(cl);  
  38.             }  
  39.         } catch (Exception e) {  
  40.             if (!mInstrumentation.onException(activity, e)) {  
  41.                 throw new RuntimeException(  
  42.                     "Unable to instantiate activity " + component  
  43.                     + ": " + e.toString(), e);  
  44.             }  
  45.         }  
  46.   
  47.   
  48.         try {  
  49.         <span style="white-space:pre">    </span>  
  50.         <span style="white-space:pre">    </span>//创建Application次数其实也是通过反射方式来创建的。  
  51.             Application app = r.packageInfo.makeApplication(false, mInstrumentation);  
  52.   
  53.   
  54.             if (localLOGV) Slog.v(TAG, "Performing launch of " + r);  
  55.             if (localLOGV) Slog.v(  
  56.                     TAG, r + ": app=" + app  
  57.                     + ", appName=" + app.getPackageName()  
  58.                     + ", pkg=" + r.packageInfo.getPackageName()  
  59.                     + ", comp=" + r.intent.getComponent().toShortString()  
  60.                     + ", dir=" + r.packageInfo.getAppDir());  
  61.   
  62.   
  63.             if (activity != null) {  
  64.                 ContextImpl appContext = new ContextImpl();  
  65.                 appContext.init(r.packageInfo, r.token, this);  
  66.                 appContext.setOuterContext(activity);  
  67.                 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());  
  68.                 Configuration config = new Configuration(mCompatConfiguration);  
  69.                 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "  
  70.                         + r.activityInfo.name + " with config " + config);  
  71.                   
  72.                 //给Activity相关字段赋值,并与WindowManager进行关联  
  73.                 activity.attach(appContext, this, getInstrumentation(), r.token,  
  74.                         r.ident, app, r.intent, r.activityInfo, title, r.parent,  
  75.                         r.embeddedID, r.lastNonConfigurationInstances, config);  
  76.   
  77.   
  78.                 if (customIntent != null) {  
  79.                     activity.mIntent = customIntent;  
  80.                 }  
  81.                 r.lastNonConfigurationInstances = null;  
  82.                 activity.mStartedActivity = false;  
  83.                 int theme = r.activityInfo.getThemeResource();  
  84.                 if (theme != 0) {  
  85.                     activity.setTheme(theme);  
  86.                 }  
  87.   
  88.   
  89.                 activity.mCalled = false;  
  90.                 //回调Activity的Oncreate方法  
  91.                 mInstrumentation.callActivityOnCreate(activity, r.state);  
  92.                 if (!activity.mCalled) {  
  93.                     throw new SuperNotCalledException(  
  94.                         "Activity " + r.intent.getComponent().toShortString() +  
  95.                         " did not call through to super.onCreate()");  
  96.                 }  
  97.                 r.activity = activity;  
  98.                 r.stopped = true;  
  99.                 if (!r.activity.mFinished) {  
  100.                     activity.performStart();  
  101.                     r.stopped = false;  
  102.                 }  
  103.                 if (!r.activity.mFinished) {  
  104.                     if (r.state != null) {  
  105.                         mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);  
  106.                     }  
  107.                 }  
  108.                 if (!r.activity.mFinished) {  
  109.                     activity.mCalled = false;  
  110.                     mInstrumentation.callActivityOnPostCreate(activity, r.state);  
  111.                     if (!activity.mCalled) {  
  112.                         throw new SuperNotCalledException(  
  113.                             "Activity " + r.intent.getComponent().toShortString() +  
  114.                             " did not call through to super.onPostCreate()");  
  115.                     }  
  116.                 }  
  117.             }  
  118.             r.paused = true;  
  119.   
  120.   
  121.             mActivities.put(r.token, r);  
  122.   
  123.   
  124.         } catch (SuperNotCalledException e) {  
  125.             throw e;  
  126.   
  127.   
  128.         } catch (Exception e) {  
  129.             if (!mInstrumentation.onException(activity, e)) {  
  130.                 throw new RuntimeException(  
  131.                     "Unable to start activity " + component  
  132.                     + ": " + e.toString(), e);  
  133.             }  
  134.         }  
  135.   
  136.   
  137.         return activity;  
  138.     }  


[java] view plaincopy
  1. Activity activity = null;  
  2.        try {  
  3.            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();  
  4.            activity = mInstrumentation.newActivity(  
  5.                    cl, component.getClassName(), r.intent);  
  6.            StrictMode.incrementExpectedActivityCount(activity.getClass());  
  7.            r.intent.setExtrasClassLoader(cl);  
  8.            if (r.state != null) {  
  9.                r.state.setClassLoader(cl);  
  10.            }  
  11.        } catch (Exception e) {  
  12.            if (!mInstrumentation.onException(activity, e)) {  
  13.                throw new RuntimeException(  
  14.                    "Unable to instantiate activity " + component  
  15.                    + ": " + e.toString(), e);  
  16.            }  
  17.        }  

此段代码就是创建Activity

mInstrumentation是Instrumentation的实例对象,

看Instrumentation的 newActivity()方法

[java] view plaincopy
  1. public Activity newActivity(ClassLoader cl, String className,  
  2.            Intent intent)  
  3.            throws InstantiationException, IllegalAccessException,  
  4.            ClassNotFoundException {  
  5.        return (Activity)cl.loadClass(className).newInstance();  
  6.    }  

发现其实就是通过反射的方式来创建一个Activity的实例对象。


然后handleLaunchActivity方法中会调用

[java] view plaincopy
  1. handleResumeActivity(r.token, false, r.isForward);  
去让Activity resume,


下面看

[java] view plaincopy
  1. final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {  
  2.       // If we are getting ready to gc after going to the background, well  
  3.       // we are back active so skip it.  
  4.       unscheduleGcIdler();  
  5.   
  6.       ActivityClientRecord r = performResumeActivity(token, clearHide);  
  7.   
  8.       if (r != null) {  
  9.           final Activity a = r.activity;  
  10.   
  11.           if (localLOGV) Slog.v(  
  12.               TAG, "Resume " + r + " started activity: " +  
  13.               a.mStartedActivity + ", hideForNow: " + r.hideForNow  
  14.               + ", finished: " + a.mFinished);  
  15.   
  16.           final int forwardBit = isForward ?  
  17.                   WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;  
  18.   
  19.           // If the window hasn't yet been added to the window manager,  
  20.           // and this guy didn't finish itself or start another activity,  
  21.           // then go ahead and add the window.  
  22.           boolean willBeVisible = !a.mStartedActivity;  
  23.           if (!willBeVisible) {  
  24.               try {  
  25.                   willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(  
  26.                           a.getActivityToken());  
  27.               } catch (RemoteException e) {  
  28.               }  
  29.           }//下面就是将activity的Veiw添加到手机的窗口的代码逻辑  
  30.           if (r.window == null && !a.mFinished && willBeVisible) {  
  31.               r.window = r.activity.getWindow();  
  32.               View decor = r.window.getDecorView();  
  33.               decor.setVisibility(View.INVISIBLE);  
  34.               ViewManager wm = a.getWindowManager();  
  35.               WindowManager.LayoutParams l = r.window.getAttributes();  
  36.               a.mDecor = decor;  
  37.               l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;  
  38.               l.softInputMode |= forwardBit;  
  39.               if (a.mVisibleFromClient) {  
  40.                   a.mWindowAdded = true;  
  41.                   wm.addView(decor, l);  
  42.               }  
  43.   
  44.           // If the window has already been added, but during resume  
  45.           // we started another activity, then don't yet make the  
  46.           // window visible.  
  47.           } else if (!willBeVisible) {  
  48.               if (localLOGV) Slog.v(  
  49.                   TAG, "Launch " + r + " mStartedActivity set");  
  50.               r.hideForNow = true;  
  51.           }  
  52.   
  53.           // Get rid of anything left hanging around.  
  54.           cleanUpPendingRemoveWindows(r);  
  55.   
  56.           // The window is now visible if it has been added, we are not  
  57.           // simply finishing, and we are not starting another activity.  
  58.           if (!r.activity.mFinished && willBeVisible  
  59.                   && r.activity.mDecor != null && !r.hideForNow) {  
  60.               if (r.newConfig != null) {  
  61.                   if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "  
  62.                           + r.activityInfo.name + " with newConfig " + r.newConfig);  
  63.                   performConfigurationChanged(r.activity, r.newConfig);  
  64.                   r.newConfig = null;  
  65.               }  
  66.               if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="  
  67.                       + isForward);  
  68.               WindowManager.LayoutParams l = r.window.getAttributes();  
  69.               if ((l.softInputMode  
  70.                       & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)  
  71.                       != forwardBit) {  
  72.                   l.softInputMode = (l.softInputMode  
  73.                           & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))  
  74.                           | forwardBit;  
  75.                   if (r.activity.mVisibleFromClient) {  
  76.                       ViewManager wm = a.getWindowManager();  
  77.                       View decor = r.window.getDecorView();  
  78.                       wm.updateViewLayout(decor, l);  
  79.                   }  
  80.               }  
  81.               r.activity.mVisibleFromServer = true;  
  82.               mNumVisibleActivities++;  
  83.               if (r.activity.mVisibleFromClient) {  
  84.                   r.activity.makeVisible();  
  85.               }  
  86.           }  
  87.   
  88.           if (!r.onlyLocalRequest) {  
  89.               r.nextIdle = mNewActivities;  
  90.               mNewActivities = r;  
  91.               if (localLOGV) Slog.v(  
  92.                   TAG, "Scheduling idle handler for " + r);  
  93.               Looper.myQueue().addIdleHandler(new Idler());  
  94.           }  
  95.           r.onlyLocalRequest = false;  
  96.   
  97.       } else {  
  98.           // If an exception was thrown when trying to resume, then  
  99.           // just end this activity.  
  100.           try {  
  101.               ActivityManagerNative.getDefault()  
  102.                   .finishActivity(token, Activity.RESULT_CANCELED, null);  
  103.           } catch (RemoteException ex) {  
  104.           }  
  105.       }  
  106.   }   

此方法中调用了Activity的performResume()方法,performResume()又会调用Instrumentation类的callActivityOnResume()方法。callActivityOnResume方法就是通过反射的方式调用ACtivity的onResume()方法.


下面先看H类的performResume()方法

[java] view plaincopy
  1. public final ActivityClientRecord performResumeActivity(IBinder token,  
  2.            boolean clearHide) {  
  3.        ActivityClientRecord r = mActivities.get(token);  
  4.        if (localLOGV) Slog.v(TAG, "Performing resume of " + r  
  5.                + " finished=" + r.activity.mFinished);  
  6.        if (r != null && !r.activity.mFinished) {  
  7.            if (clearHide) {  
  8.                r.hideForNow = false;  
  9.                r.activity.mStartedActivity = false;  
  10.            }  
  11.            try {  
  12.                if (r.pendingIntents != null) {  
  13.                    deliverNewIntents(r, r.pendingIntents);  
  14.                    r.pendingIntents = null;  
  15.                }  
  16.                if (r.pendingResults != null) {  
  17.                    deliverResults(r, r.pendingResults);  
  18.                    r.pendingResults = null;  
  19.                }  
  20.                //调用Activity的performResume()方法  
  21.                r.activity.performResume();  
  22.   
  23.                EventLog.writeEvent(LOG_ON_RESUME_CALLED,  
  24.                        r.activity.getComponentName().getClassName());  
  25.   
  26.                r.paused = false;  
  27.                r.stopped = false;  
  28.                r.state = null;  
  29.            } catch (Exception e) {  
  30.                if (!mInstrumentation.onException(r.activity, e)) {  
  31.                    throw new RuntimeException(  
  32.                        "Unable to resume activity "  
  33.                        + r.intent.getComponent().toShortString()  
  34.                        + ": " + e.toString(), e);  
  35.                }  
  36.            }  
  37.        }  
  38.        return r;  
  39.    }  
下面再看Activity的performResume()方法

[java] view plaincopy
  1. final void performResume() {  
  2.         performRestart();  
  3.           
  4.         mFragments.execPendingActions();  
  5.           
  6.         mLastNonConfigurationInstances = null;  
  7.           
  8.         mCalled = false;  
  9.         // mResumed is set by the instrumentation  
[java] view plaincopy
  1. //Instrumentation类的callActivityOnResume()方法  
[java] view plaincopy
  1. mInstrumentation.callActivityOnResume(this);  
  2. sp;  
[java] view plaincopy
  1.  </span>  if (!mCalled) {  
  2.             throw new SuperNotCalledException(  
  3.                 "Activity " + mComponent.toShortString() +  
  4.                 " did not call through to super.onResume()");  
  5.         }  
  6.   
  7.         // Now really resume, and install the current status bar and menu.  
  8.         mCalled = false;  
  9.           
  10.         mFragments.dispatchResume();  
  11.         mFragments.execPendingActions();  
  12.           
  13.         onPostResume();  
  14.         if (!mCalled) {  
  15.             throw new SuperNotCalledException(  
  16.                 "Activity " + mComponent.toShortString() +  
  17.                 " did not call through to super.onPostResume()");  
  18.         }  
  19.     }  
再看Instrumentation类的callActivityOnResume()方法,其实就是就是回调Activity的onResume()方法

[java] view plaincopy
  1. public void callActivityOnResume(Activity activity) {  
  2.         activity.mResumed = true;  
  3.      //回调Activity的onResume()方法  
  4.         activity.onResume();  
  5.           
  6.         if (mActivityMonitors != null) {  
  7.             synchronized (mSync) {  
  8.                 final int N = mActivityMonitors.size();  
  9.                 for (int i=0; i<N; i++) {  
  10.                     final ActivityMonitor am = mActivityMonitors.get(i);  
  11.                     am.match(activity, activity, activity.getIntent());  
  12.                 }  
  13.             }  
  14.         }  
  15.     }  

到此时Activity的onResume方法已经被调用了,但是关于界面的东西并没有看到,其实handleResumeActivity()方法的一下代码片段就是将Activity的Veiw添加到手机的窗口,并且显示出来。

[java] view plaincopy
  1. //下面就是将activity的Veiw添加到手机的窗口的代码逻辑  
  2.             if (r.window == null && !a.mFinished && willBeVisible) {  
  3.                 r.window = r.activity.getWindow();  
  4.                 View decor = r.window.getDecorView();  
  5.                 decor.setVisibility(View.INVISIBLE);  
  6.                 ViewManager wm = a.getWindowManager();  
  7.                 WindowManager.LayoutParams l = r.window.getAttributes();  
  8.                 a.mDecor = decor;  
  9.                 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;  
  10.                 l.softInputMode |= forwardBit;  
  11.                 if (a.mVisibleFromClient) {  
  12.                     a.mWindowAdded = true;  
  13.                     wm.addView(decor, l);  
  14.                 }  


decor是Activity的跟View,他是一个PhoneView,而PhoneView又继承了FrameLayout,所以decor归根结底是一个FrameLayout。

wm 是在Activity的attach方法中初始化的

 
[java] view plaincopy
  1. final void attach(Context context, ActivityThread aThread,  
  2.            Instrumentation instr, IBinder token, int ident,  
  3.            Application application, Intent intent, ActivityInfo info,  
  4.            CharSequence title, Activity parent, String id,  
  5.            NonConfigurationInstances lastNonConfigurationInstances,  
  6.            Configuration config) {  
  7.         
  8.                 ....  
  9.   
  10.        mWindow.setWindowManager(null, mToken, mComponent.flattenToString(),  
  11.                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);  
  12.        if (mParent != null) {  
  13.            mWindow.setContainer(mParent.getWindow());  
  14.        }  
  15.        mWindowManager = mWindow.getWindowManager();  
  16.        mCurrentConfig = config;  
  17.    }  

再看Window的setWindowManager方法

[java] view plaincopy
  1. public void setWindowManager(WindowManager wm, IBinder appToken, String appName) {  
  2.        setWindowManager(wm, appToken, appName, false);  
  3.    }  
  4.   
  5.    /** 
  6.     * Set the window manager for use by this Window to, for example, 
  7.     * display panels.  This is <em>not</em> used for displaying the 
  8.     * Window itself -- that must be done by the client. 
  9.     * 
  10.     * @param wm The ViewManager for adding new windows. 
  11.     */  
  12.    public void setWindowManager(WindowManager wm, IBinder appToken, String appName,  
  13.            boolean hardwareAccelerated) {  
  14.        mAppToken = appToken;  
  15.        mAppName = appName;  
  16.        if (wm == null) {  
  17.            wm = WindowManagerImpl.getDefault();  
  18.        }  
  19.        mWindowManager = new LocalWindowManager(wm, hardwareAccelerated);  
  20.    }  

发现WindowManager 的实例为LocalWindowManager类型的;
LocalWindowManager是WindowManagerImpl.CompatModeWrapper的子类
WindowManagerImpl.CompatModeWrapper是WindowManager的子类
WindowManager实现了ViewManager的子类

ViewManager是一个接口,管理Activity的View添加 删除,更新

[java] view plaincopy
  1. package android.view;  
  2.   
  3. /** Interface to let you add and remove child views to an Activity. To get an instance 
  4.   * of this class, call {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}. 
  5.   */  
  6. public interface ViewManager  
  7. {  
  8.     public void addView(View view, ViewGroup.LayoutParams params);  
  9.     public void updateViewLayout(View view, ViewGroup.LayoutParams params);  
  10.     public void removeView(View view);  
  11. }  

handleResumeActivity()方法中的


[java] view plaincopy
  1. ....  
[java] view plaincopy
  1.    if (a.mVisibleFromClient) {  
  2.                     a.mWindowAdded = true;  
  3.                     wm.addView(decor, l);  
  4.                 }  

[java] view plaincopy
  1. ....  


其实就是将Activity的根View decor添加到手机屏幕并显示,下面看LocalWindowManager的addView方法

[java] view plaincopy
  1. public final void addView(View view, ViewGroup.LayoutParams params) {  
  2.             // Let this throw an exception on a bad params.  
  3.             WindowManager.LayoutParams wp = (WindowManager.LayoutParams)params;  
  4.             CharSequence curTitle = wp.getTitle();  
  5.             if (wp.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&  
  6.                 wp.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {  
  7.                 if (wp.token == null) {  
  8.                     View decor = peekDecorView();  
  9.                     if (decor != null) {  
  10.                         wp.token = decor.getWindowToken();  
  11.                     }  
  12.                 }  
  13.                 if (curTitle == null || curTitle.length() == 0) {  
  14.                     String title;  
  15.                     if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA) {  
  16.                         title="Media";  
  17.                     } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY) {  
  18.                         title="MediaOvr";  
  19.                     } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {  
  20.                         title="Panel";  
  21.                     } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL) {  
  22.                         title="SubPanel";  
  23.                     } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG) {  
  24.                         title="AtchDlg";  
  25.                     } else {  
  26.                         title=Integer.toString(wp.type);  
  27.                     }  
  28.                     if (mAppName != null) {  
  29.                         title += ":" + mAppName;  
  30.                     }  
  31.                     wp.setTitle(title);  
  32.                 }  
  33.             } else {  
  34.                 if (wp.token == null) {  
  35.                     wp.token = mContainer == null ? mAppToken : mContainer.mAppToken;  
  36.                 }  
  37.                 if ((curTitle == null || curTitle.length() == 0)  
  38.                         && mAppName != null) {  
  39.                     wp.setTitle(mAppName);  
  40.                 }  
  41.            }  
  42.             if (wp.packageName == null) {  
  43.                 wp.packageName = mContext.getPackageName();  
  44.             }  
  45.             if (mHardwareAccelerated) {  
  46.                 wp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;  
  47.             }  [java] view plaincopy
  1.  //调用父类的方法  
  2.             super.addView(view, params);  
  3.         }  
  4.     }  

我们看他的父类WindowManagerImpl.CompatModeWrapper的子类的addView方法

[java] view plaincopy
  1. @Override  
  2.         public void addView(View view, android.view.ViewGroup.LayoutParams params) {  
  3.             mWindowManager.addView(view, params, mCompatibilityInfo);  
  4.         }  

mWindowManager是在CompatModeWrapper的构造方法中初始化,他是WindowManagerImpl类型的。

 

[java] view plaincopy
  1. CompatModeWrapper(WindowManager wm, CompatibilityInfoHolder ci) {  
  2.            //  
[java] view plaincopy
  1.  mWindowManager = wm instanceof CompatModeWrapper  
  2.                     ? ((CompatModeWrapper)wm).mWindowManager : (WindowManagerImpl)wm;  
  3.   
  4.   
  5.             // Use the original display if there is no compatibility mode  
  6.             // to apply, or the underlying window manager is already a  
  7.             // compatibility mode wrapper.  (We assume that if it is a  
  8.             // wrapper, it is applying the same compatibility mode.)  
  9.             if (ci == null) {  
  10.                 mDefaultDisplay = mWindowManager.getDefaultDisplay();  
  11.             } else {  
  12.                 //mDefaultDisplay = mWindowManager.getDefaultDisplay();  
  13.                 mDefaultDisplay = Display.createCompatibleDisplay(  
  14.                         mWindowManager.getDefaultDisplay().getDisplayId(), ci);  
  15.             }  
  16.   
  17.   
  18.             mCompatibilityInfo = ci;  
  19.         }  

所以addVeiw调用的都是WindowManagerImpl的addVeiw的方法。WindowManagerImpl有多个addVeiw重载函数,但最终都是调用下面这个方法

该方法会创建一个ViewRootImp实例对象,ViewRootImp是实现每一个具体类的管理的核心类,ViewRootImp中的内部类W实现与WindowManager的交互。

每一个Activity都对应一个ViewRootImp实例对象


[java] view plaincopy
  1. private void addView(View view, ViewGroup.LayoutParams params,  
  2.             CompatibilityInfoHolder cih, boolean nest) {  
  3.         if (false) Log.v("WindowManager""addView view=" + view);  
  4.   
  5.   
  6.         if (!(params instanceof WindowManager.LayoutParams)) {  
  7.             throw new IllegalArgumentException(  
  8.                     "Params must be WindowManager.LayoutParams");  
  9.         }  
  10.   
  11.   
  12.         final WindowManager.LayoutParams wparams  
  13.                 = (WindowManager.LayoutParams)params;  
  14.           
  15.         ViewRootImpl root;  
  16.         View panelParentView = null;  
  17.           
  18.         synchronized (this) {  
  19.             // Here's an odd/questionable case: if someone tries to add a  
  20.             // view multiple times, then we simply bump up a nesting count  
  21.             // and they need to remove the view the corresponding number of  
  22.             // times to have it actually removed from the window manager.  
  23.             // This is useful specifically for the notification manager,  
  24.             // which can continually add/remove the same view as a  
  25.             // notification gets updated.  
  26.             int index = findViewLocked(view, false);  
  27.             if (index >= 0) {  
  28.                 if (!nest) {  
  29.                     throw new IllegalStateException("View " + view  
  30.                             + " has already been added to the window manager.");  
  31.                 }  
  32.                 root = mRoots[index];  
  33.                 root.mAddNesting++;  
  34.                 // Update layout parameters.  
  35.                 view.setLayoutParams(wparams);  
  36.                 root.setLayoutParams(wparams, true);  
  37.                 return;  
  38.             }  
  39.               
  40.             // If this is a panel window, then find the window it is being  
  41.             // attached to for future reference.  
  42.             if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&  
  43.                     wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {  
  44.                 final int count = mViews != null ? mViews.length : 0;  
  45.                 for (int i=0; i<count; i++) {  
  46.                     if (mRoots[i].mWindow.asBinder() == wparams.token) {  
  47.                         panelParentView = mViews[i];  
  48.                     }  
  49.                 }  
  50.             }  
  51.               
  52.             root = new ViewRootImpl(view.getContext());  
  53.             root.mAddNesting = 1;  
  54.             if (cih == null) {  
  55.                 root.mCompatibilityInfo = new CompatibilityInfoHolder();  
  56.             } else {  
  57.                 root.mCompatibilityInfo = cih;  
  58.             }  
  59.   
  60.   
  61.             view.setLayoutParams(wparams);  
  62.               
  63.             if (mViews == null) {  
  64.                 index = 1;  
  65.                 mViews = new View[1];  
  66.                 mRoots = new ViewRootImpl[1];  
  67.                 mParams = new WindowManager.LayoutParams[1];  
  68.             } else {  
  69.                 index = mViews.length + 1;  
  70.                 Object[] old = mViews;  
  71.                 mViews = new View[index];  
  72.                 System.arraycopy(old, 0, mViews, 0, index-1);  
  73.                 old = mRoots;  
  74.                 mRoots = new ViewRootImpl[index];  
  75.                 System.arraycopy(old, 0, mRoots, 0, index-1);  
  76.                 old = mParams;  
  77.                 mParams = new WindowManager.LayoutParams[index];  
  78.                 System.arraycopy(old, 0, mParams, 0, index-1);  
  79.             }  
  80.             index--;  
  81.   
  82.   
  83.         //每一Activity对应一个View(decor)  
  84.             mViews[index] = view;  
  85.               
  86.        //每一个Activity都对应一个ViewRootImp实例对象          
  87.        mRoots[index] = root;  
  88.              
  89.            mParams[index] = wparams;  
  90.         }  
  91.         // do this last because it fires off messages to start doing things  
  92.        //让ViewRootImp与当前要显示的View进行关联  
  93.         root.setView(view, wparams, panelParentView);  
  94.     }  


下面看ViewRootImpl 的setView方法

[java] view plaincopy
  1. public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {  
  2.        synchronized (this) {  
  3.            <span style="white-space:pre"> </span>.......  
  4.     .......  
  5.     .......  
  6.   
  7.                // Schedule the first layout -before- adding to the window  
  8.                // manager, to make sure we do the relayout before receiving  
  9.                // any other events from the system.  
  10.                requestLayout();  
  11.     .......  
  12.     .......  
  13.     .......  
[java] view plaincopy
  1. <span style="white-space:pre">        </span>//给View设置一个父View,这里的父子关系不是继承关系,而是一种包含关系  
  2.                 view.assignParent(this);  
  3.                  
  4.   
  5.                 .......  
  6.         .......  
  7.         .......  
  8.                 }  
  9.             }  
  10.         }  
  11.     }  


每一个View都会有一个Parent view,我们Activity的decor的父View就是ViewRootImpl ,decor的所有子View都是由ViewRootImp统一管理,例如,一个View调用自己的invalidata()方法更新自己,都会一次向上传递给ViewRootImp,然后由ViewRootImp对每一个View的情况进行汇总,然后在统一更新。


到目前为止Activity的View还是没有显示出来。

handleResumeActivity()方法中以下语句就是让Activity的View显示出来

[java] view plaincopy
  1. ......  
  2. activity.makeVisible();  
  3. .......  
下面看Activity的 makeVisible()方法,其实就是让mDecor显示出来。到此界面终于出来啦。

[java] view plaincopy
  1. void makeVisible() {  
  2.         if (!mWindowAdded) {  
  3.             ViewManager wm = getWindowManager();  
  4.             wm.addView(mDecor, getWindow().getAttributes());  
  5.             mWindowAdded = true;  
  6.         }  
  7.         mDecor.setVisibility(View.VISIBLE);  
  8.     }  

0 0
原创粉丝点击