久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Android系統(tǒng)默認(rèn)Home應(yīng)用程序(Launcher)的啟動過程源代碼分析

 jemeen 2012-02-03

 在前面一篇文章中,,我們分析了Android系統(tǒng)在啟動時安裝應(yīng)用程序的過程,這些應(yīng)用程序安裝好之后,,還需要有一個Home應(yīng)用程序來負(fù)責(zé)把它們在桌面上展示出來,,在Android系統(tǒng)中,這個默認(rèn)的Home應(yīng)用程序就是Launcher了,,本文將詳細(xì)分析Launcher應(yīng)用程序的啟動過程,。

        Android系統(tǒng)的Home應(yīng)用程序Launcher是由ActivityManagerService啟動的,,而ActivityManagerService和PackageManagerService一樣,,都是在開機(jī)時由SystemServer組件啟動的,SystemServer組件首先是啟動ePackageManagerServic,,由它來負(fù)責(zé)安裝系統(tǒng)的應(yīng)用程序,,具體可以參考前面一篇文章Android應(yīng)用程序安裝過程源代碼分析,系統(tǒng)中的應(yīng)用程序安裝好了以后,,SystemServer組件接下來就要通過ActivityManagerService來啟動Home應(yīng)用程序Launcher了,,Launcher在啟動的時候便會通過PackageManagerServic把系統(tǒng)中已經(jīng)安裝好的應(yīng)用程序以快捷圖標(biāo)的形式展示在桌面上,這樣用戶就可以使用這些應(yīng)用程序了,整個過程如下圖所示:


點擊查看大圖

        下面詳細(xì)分析每一個步驟,。

        Step 1. SystemServer.main

        這個函數(shù)定義在frameworks/base/services/java/com/android/server/SystemServer.java文件中,,具體可以參考前面一篇文章Android應(yīng)用程序安裝過程源代碼分析的Step 1。

        Step 2. SystemServer.init1

        這個函數(shù)是一個JNI方法,,實現(xiàn)在 frameworks/base/services/jni/com_android_server_SystemServer.cpp文件中,,具體可以參考前面一篇文章Android應(yīng)用程序安裝過程源代碼分析的Step 2。

        Step 3. libsystem_server.system_init

        函數(shù)system_init實現(xiàn)在libsystem_server庫中,,源代碼位于frameworks/base/cmds/system_server/library/system_init.cpp文件中,,具體可以參考前面一篇文章Android應(yīng)用程序安裝過程源代碼分析的Step 3。

        Step 4. AndroidRuntime.callStatic

        這個函數(shù)定義在frameworks/base/core/jni/AndroidRuntime.cpp文件中,,具體可以參考前面一篇文章Android應(yīng)用程序安裝過程源代碼分析的Step 4,。

        Step 5. SystemServer.init2

        這個函數(shù)定義在frameworks/base/services/java/com/android/server/SystemServer.java文件中,具體可以參考前面一篇文章Android應(yīng)用程序安裝過程源代碼分析的Step 5,。

        Step 6. ServerThread.run

        這個函數(shù)定義在frameworks/base/services/java/com/android/server/SystemServer.java文件中,,具體可以參考前面一篇文章Android應(yīng)用程序安裝過程源代碼分析的Step 6。

        Step 7. ActivityManagerService.main

        這個函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerServcie.java文件中:

  1. public final class ActivityManagerService extends ActivityManagerNative  
  2.         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {  
  3.     ......  
  4.   
  5.     public static final Context main(int factoryTest) {  
  6.         AThread thr = new AThread();  
  7.         thr.start();  
  8.   
  9.         synchronized (thr) {  
  10.             while (thr.mService == null) {  
  11.                 try {  
  12.                     thr.wait();  
  13.                 } catch (InterruptedException e) {  
  14.                 }  
  15.             }  
  16.         }  
  17.   
  18.         ActivityManagerService m = thr.mService;  
  19.         mSelf = m;  
  20.         ActivityThread at = ActivityThread.systemMain();  
  21.         mSystemThread = at;  
  22.         Context context = at.getSystemContext();  
  23.         m.mContext = context;  
  24.         m.mFactoryTest = factoryTest;  
  25.         m.mMainStack = new ActivityStack(m, context, true);  
  26.   
  27.         m.mBatteryStatsService.publish(context);  
  28.         m.mUsageStatsService.publish(context);  
  29.   
  30.         synchronized (thr) {  
  31.             thr.mReady = true;  
  32.             thr.notifyAll();  
  33.         }  
  34.   
  35.         m.startRunning(nullnullnullnull);  
  36.   
  37.         return context;  
  38.     }  
  39.   
  40.     ......  
  41. }  
        這個函數(shù)首先通過AThread線程對象來內(nèi)部創(chuàng)建了一個ActivityManagerService實例,,然后將這個實例保存其成員變量mService中,,接著又把這個ActivityManagerService實例保存在ActivityManagerService類的靜態(tài)成員變量mSelf中,最后初始化其它成員變量,,就結(jié)束了,。

        Step 8. PackageManagerService.main

        這個函數(shù)定義在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中,具體可以參考前面一篇文章Android應(yīng)用程序安裝過程源代碼分析的Step 7,。執(zhí)行完這一步之后,,系統(tǒng)中的應(yīng)用程序的所有信息都保存在PackageManagerService中了,后面Home應(yīng)用程序Launcher啟動起來后,,就會把PackageManagerService中的應(yīng)用程序信息取出來,,然后以快捷圖標(biāo)的形式展示在桌面上,后面我們將會看到這個過程,。

        Step 9. ActivityManagerService.setSystemProcess

        這個函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerServcie.java文件中:

  1. public final class ActivityManagerService extends ActivityManagerNative  
  2.         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {  
  3.     ......  
  4.   
  5.     public static void setSystemProcess() {  
  6.         try {  
  7.             ActivityManagerService m = mSelf;  
  8.   
  9.             ServiceManager.addService("activity", m);  
  10.             ServiceManager.addService("meminfo"new MemBinder(m));  
  11.             if (MONITOR_CPU_USAGE) {  
  12.                 ServiceManager.addService("cpuinfo"new CpuBinder(m));  
  13.             }  
  14.             ServiceManager.addService("permission"new PermissionController(m));  
  15.   
  16.             ApplicationInfo info =  
  17.                 mSelf.mContext.getPackageManager().getApplicationInfo(  
  18.                 "android", STOCK_PM_FLAGS);  
  19.             mSystemThread.installSystemApplicationInfo(info);  
  20.   
  21.             synchronized (mSelf) {  
  22.                 ProcessRecord app = mSelf.newProcessRecordLocked(  
  23.                     mSystemThread.getApplicationThread(), info,  
  24.                     info.processName);  
  25.                 app.persistent = true;  
  26.                 app.pid = MY_PID;  
  27.                 app.maxAdj = SYSTEM_ADJ;  
  28.                 mSelf.mProcessNames.put(app.processName, app.info.uid, app);  
  29.                 synchronized (mSelf.mPidsSelfLocked) {  
  30.                     mSelf.mPidsSelfLocked.put(app.pid, app);  
  31.                 }  
  32.                 mSelf.updateLruProcessLocked(app, truetrue);  
  33.             }  
  34.         } catch (PackageManager.NameNotFoundException e) {  
  35.             throw new RuntimeException(  
  36.                 "Unable to find android system package", e);  
  37.         }  
  38.     }  
  39.     ......  
  40. }  
        這個函數(shù)首先是將這個ActivityManagerService實例添加到ServiceManager中去托管,,這樣其它地方就可以通過ServiceManager.getService接口來訪問這個全局唯一的ActivityManagerService實例了,接著又通過調(diào)用mSystemThread.installSystemApplicationInfo函數(shù)來把應(yīng)用程序框架層下面的android包加載進(jìn)來 ,,這里的mSystemThread是一個ActivityThread類型的實例變量,,它是在上面的Step 7中創(chuàng)建的,后面就是一些其它的初始化工作了,。

        Step 10.  ActivityManagerService.systemReady

        這個函數(shù)是在上面的Step 6中的ServerThread.run函數(shù)在將系統(tǒng)中的一系列服務(wù)都初始化完畢之后才調(diào)用的,,它定義在frameworks/base/services/java/com/android/server/am/ActivityManagerServcie.java文件中:

  1. public final class ActivityManagerService extends ActivityManagerNative  
  2.         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {  
  3.     ......  
  4.   
  5.     public void systemReady(final Runnable goingCallback) {  
  6.         ......  
  7.   
  8.         synchronized (this) {  
  9.             ......  
  10.   
  11.             mMainStack.resumeTopActivityLocked(null);  
  12.         }  
  13.     }  
  14.   
  15.     ......  
  16. }  
        這個函數(shù)的內(nèi)容比較多,這里省去無關(guān)的部分,,主要關(guān)心啟動Home應(yīng)用程序的邏輯,,這里就是通過mMainStack.resumeTopActivityLocked函數(shù)來啟動Home應(yīng)用程序的了,,這里的mMainStack是一個ActivityStack類型的實例變量。

        Step 11. ActivityStack.resumeTopActivityLocked

        這個函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:

  1. public class ActivityStack {  
  2.     ......  
  3.   
  4.     final boolean resumeTopActivityLocked(ActivityRecord prev) {  
  5.         // Find the first activity that is not finishing.   
  6.         ActivityRecord next = topRunningActivityLocked(null);  
  7.   
  8.         ......  
  9.   
  10.         if (next == null) {  
  11.             // There are no more activities!  Let's just start up the   
  12.             // Launcher...   
  13.             if (mMainStack) {  
  14.                 return mService.startHomeActivityLocked();  
  15.             }  
  16.         }  
  17.   
  18.         ......  
  19.     }  
  20.   
  21.     ......  
  22. }  
        這里調(diào)用函數(shù)topRunningActivityLocked返回的是當(dāng)前系統(tǒng)Activity堆棧最頂端的Activity,,由于此時還沒有Activity被啟動過,,因此,返回值為null,,即next變量的值為null,,于是就調(diào)用mService.startHomeActivityLocked語句,這里的mService就是前面在Step 7中創(chuàng)建的ActivityManagerService實例了,。

        Step 12. ActivityManagerService.startHomeActivityLocked

        這個函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerServcie.java文件中:

  1. public final class ActivityManagerService extends ActivityManagerNative  
  2.         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {  
  3.     ......  
  4.   
  5.     boolean startHomeActivityLocked() {  
  6.         ......  
  7.   
  8.         Intent intent = new Intent(  
  9.             mTopAction,  
  10.             mTopData != null ? Uri.parse(mTopData) : null);  
  11.         intent.setComponent(mTopComponent);  
  12.         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {  
  13.             intent.addCategory(Intent.CATEGORY_HOME);  
  14.         }  
  15.         ActivityInfo aInfo =  
  16.             intent.resolveActivityInfo(mContext.getPackageManager(),  
  17.             STOCK_PM_FLAGS);  
  18.         if (aInfo != null) {  
  19.             intent.setComponent(new ComponentName(  
  20.                 aInfo.applicationInfo.packageName, aInfo.name));  
  21.             // Don't do this if the home app is currently being   
  22.             // instrumented.   
  23.             ProcessRecord app = getProcessRecordLocked(aInfo.processName,  
  24.                 aInfo.applicationInfo.uid);  
  25.             if (app == null || app.instrumentationClass == null) {  
  26.                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);  
  27.                 mMainStack.startActivityLocked(null, intent, nullnull0, aInfo,  
  28.                     nullnull000falsefalse);  
  29.             }  
  30.         }  
  31.   
  32.         return true;  
  33.     }  
  34.   
  35.     ......  
  36. }  
        函數(shù)首先創(chuàng)建一個CATEGORY_HOME類型的Intent,,然后通過Intent.resolveActivityInfo函數(shù)向PackageManagerService查詢Category類型為HOME的Activity,這里我們假設(shè)只有系統(tǒng)自帶的Launcher應(yīng)用程序注冊了HOME類型的Activity(見packages/apps/Launcher2/AndroidManifest.xml文件):

  1. <manifest  
  2.     xmlns:android="http://schemas./apk/res/android"  
  3.     package="com.android.launcher"  
  4.     android:sharedUserId="@string/sharedUserId"  
  5.     >  
  6.   
  7.     ......  
  8.   
  9.     <application  
  10.         android:name="com.android.launcher2.LauncherApplication"  
  11.         android:process="@string/process"  
  12.         android:label="@string/application_name"  
  13.         android:icon="@drawable/ic_launcher_home">  
  14.   
  15.         <activity  
  16.             android:name="com.android.launcher2.Launcher"  
  17.             android:launchMode="singleTask"  
  18.             android:clearTaskOnLaunch="true"  
  19.             android:stateNotNeeded="true"  
  20.             android:theme="@style/Theme"  
  21.             android:screenOrientation="nosensor"  
  22.             android:windowSoftInputMode="stateUnspecified|adjustPan">  
  23.             <intent-filter>  
  24.                 <action android:name="android.intent.action.MAIN" />  
  25.                 <category android:name="android.intent.category.HOME" />  
  26.                 <category android:name="android.intent.category.DEFAULT" />  
  27.                 <category android:name="android.intent.category.MONKEY"/>  
  28.                 </intent-filter>  
  29.         </activity>  
  30.   
  31.         ......  
  32.     </application>  
  33. </manifest>  

        因此,,這里就返回com.android.launcher2.Launcher這個Activity了,。由于是第一次啟動這個Activity,接下來調(diào)用函數(shù)getProcessRecordLocked返回來的ProcessRecord值為null,,于是,,就調(diào)用mMainStack.startActivityLocked函數(shù)啟動com.android.launcher2.Launcher這個Activity了,這里的mMainStack是一個ActivityStack類型的成員變量,。

        Step 13.  ActivityStack.startActivityLocked

        這個函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中,,具體可以參考Android應(yīng)用程序啟動過程源代碼分析一文,這里就不詳述了,,在我們這個場景中,,調(diào)用這個函數(shù)的最后結(jié)果就是把com.android.launcher2.Launcher啟動起來,接著調(diào)用它的onCreate函數(shù),。

        Step 14. Launcher.onCreate

        這個函數(shù)定義在packages/apps/Launcher2/src/com/android/launcher2/Launcher.java文件中:

  1. public final class Launcher extends Activity  
  2.         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks, AllAppsView.Watcher {  
  3.     ......  
  4.   
  5.     @Override  
  6.     protected void onCreate(Bundle savedInstanceState) {  
  7.         ......  
  8.   
  9.         if (!mRestoring) {  
  10.             mModel.startLoader(thistrue);  
  11.         }  
  12.   
  13.         ......  
  14.     }  
  15.   
  16.     ......  
  17. }  
        這里的mModel是一個LauncherModel類型的成員變量,,這里通過調(diào)用它的startLoader成員函數(shù)來執(zhí)行加應(yīng)用程序的操作。

        Step 15. LauncherModel.startLoader

        這個函數(shù)定義在packages/apps/Launcher2/src/com/android/launcher2/LauncherModel.java文件中:

  1. public class LauncherModel extends BroadcastReceiver {  
  2.     ......  
  3.   
  4.     public void startLoader(Context context, boolean isLaunching) {  
  5.         ......  
  6.   
  7.                 synchronized (mLock) {  
  8.                      ......  
  9.   
  10.                      // Don't bother to start the thread if we know it's not going to do anything   
  11.                      if (mCallbacks != null && mCallbacks.get() != null) {  
  12.                          // If there is already one running, tell it to stop.   
  13.                          LoaderTask oldTask = mLoaderTask;  
  14.                          if (oldTask != null) {  
  15.                              if (oldTask.isLaunching()) {  
  16.                                  // don't downgrade isLaunching if we're already running   
  17.                                  isLaunching = true;  
  18.                              }  
  19.                              oldTask.stopLocked();  
  20.                  }  
  21.                  mLoaderTask = new LoaderTask(context, isLaunching);  
  22.                  sWorker.post(mLoaderTask);  
  23.                 }  
  24.            }  
  25.     }  
  26.   
  27.     ......  
  28. }  
        這里不是直接加載應(yīng)用程序,,而是把加載應(yīng)用程序的操作作為一個消息來處理,。這里的sWorker是一個Handler,通過它的post方式把一個消息放在消息隊列中去,,然后系統(tǒng)就會調(diào)用傳進(jìn)去的參數(shù)mLoaderTask的run函數(shù)來處理這個消息,,這個mLoaderTask是LoaderTask類型的實例,于是,,下面就會執(zhí)行LoaderTask類的run函數(shù)了,。

        Step 16. LoaderTask.run

        這個函數(shù)定義在packages/apps/Launcher2/src/com/android/launcher2/LauncherModel.java文件中:

  1. public class LauncherModel extends BroadcastReceiver {  
  2.     ......  
  3.   
  4.     private class LoaderTask implements Runnable {  
  5.         ......  
  6.   
  7.         public void run() {  
  8.             ......  
  9.   
  10.             keep_running: {  
  11.                 ......  
  12.   
  13.                 // second step   
  14.                 if (loadWorkspaceFirst) {  
  15.                     ......  
  16.                     loadAndBindAllApps();  
  17.                 } else {  
  18.                     ......  
  19.                 }  
  20.   
  21.                 ......  
  22.             }  
  23.   
  24.             ......  
  25.         }  
  26.   
  27.         ......  
  28.     }  
  29.   
  30.     ......  
  31. }  
        這里調(diào)用loadAndBindAllApps成員函數(shù)來進(jìn)一步操作。

        Step 17. LoaderTask.loadAndBindAllApps
        這個函數(shù)定義在packages/apps/Launcher2/src/com/android/launcher2/LauncherModel.java文件中:

  1. public class LauncherModel extends BroadcastReceiver {  
  2.     ......  
  3.   
  4.     private class LoaderTask implements Runnable {  
  5.         ......  
  6.   
  7.         private void loadAndBindAllApps() {  
  8.             ......  
  9.   
  10.             if (!mAllAppsLoaded) {  
  11.                 loadAllAppsByBatch();  
  12.                 if (mStopped) {  
  13.                     return;  
  14.                 }  
  15.                 mAllAppsLoaded = true;  
  16.             } else {  
  17.                 onlyBindAllApps();  
  18.             }  
  19.         }  
  20.   
  21.   
  22.         ......  
  23.     }  
  24.   
  25.     ......  
  26. }  
        由于還沒有加載過應(yīng)用程序,,這里的mAllAppsLoaded為false,,于是就繼續(xù)調(diào)用loadAllAppsByBatch函數(shù)來進(jìn)一步操作了,。

        Step 18. LoaderTask.loadAllAppsByBatch
        這個函數(shù)定義在packages/apps/Launcher2/src/com/android/launcher2/LauncherModel.java文件中:

  1. public class LauncherModel extends BroadcastReceiver {  
  2.     ......  
  3.   
  4.     private class LoaderTask implements Runnable {  
  5.         ......  
  6.   
  7.         private void loadAllAppsByBatch() {   
  8.             ......  
  9.   
  10.             final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);  
  11.             mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);  
  12.   
  13.             final PackageManager packageManager = mContext.getPackageManager();  
  14.             List<ResolveInfo> apps = null;  
  15.   
  16.             int N = Integer.MAX_VALUE;  
  17.   
  18.             int startIndex;  
  19.             int i=0;  
  20.             int batchSize = -1;  
  21.             while (i < N && !mStopped) {  
  22.                 if (i == 0) {  
  23.                     mAllAppsList.clear();  
  24.                     ......  
  25.                     apps = packageManager.queryIntentActivities(mainIntent, 0);  
  26.                       
  27.                     ......  
  28.   
  29.                     N = apps.size();  
  30.                       
  31.                     ......  
  32.   
  33.                     if (mBatchSize == 0) {  
  34.                         batchSize = N;  
  35.                     } else {  
  36.                         batchSize = mBatchSize;  
  37.                     }  
  38.   
  39.                     ......  
  40.   
  41.                     Collections.sort(apps,  
  42.                         new ResolveInfo.DisplayNameComparator(packageManager));  
  43.                 }  
  44.   
  45.                 startIndex = i;  
  46.                 for (int j=0; i<N && j<batchSize; j++) {  
  47.                     // This builds the icon bitmaps.   
  48.                     mAllAppsList.add(new ApplicationInfo(apps.get(i), mIconCache));  
  49.                     i++;  
  50.                 }  
  51.   
  52.                 final boolean first = i <= batchSize;  
  53.                 final Callbacks callbacks = tryGetCallbacks(oldCallbacks);  
  54.                 final ArrayList<ApplicationInfo> added = mAllAppsList.added;  
  55.                 mAllAppsList.added = new ArrayList<ApplicationInfo>();  
  56.               
  57.                 mHandler.post(new Runnable() {  
  58.                     public void run() {  
  59.                         final long t = SystemClock.uptimeMillis();  
  60.                         if (callbacks != null) {  
  61.                             if (first) {  
  62.                                 callbacks.bindAllApplications(added);  
  63.                             } else {  
  64.                                 callbacks.bindAppsAdded(added);  
  65.                             }  
  66.                             ......  
  67.                         } else {  
  68.                             ......  
  69.                         }  
  70.                     }  
  71.                 });  
  72.   
  73.                 ......  
  74.             }  
  75.   
  76.             ......  
  77.         }  
  78.   
  79.         ......  
  80.     }  
  81.   
  82.     ......  
  83. }  
        函數(shù)首先構(gòu)造一個CATEGORY_LAUNCHER類型的Intent:

  1. final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);  
  2. mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);  
        接著從mContext變量中獲得PackageManagerService的接口:

  1. final PackageManager packageManager = mContext.getPackageManager();  

       下一步就是通過這個PackageManagerService.queryIntentActivities接口來取回所有Action類型為Intent.ACTION_MAIN,,并且Category類型為Intent.CATEGORY_LAUNCHER的Activity了,。

       我們先進(jìn)入到PackageManagerService.queryIntentActivities函數(shù)中看看是如何獲得這些Activity的,然后再回到這個函數(shù)中來看其余操作,。

       Step 19. PackageManagerService.queryIntentActivities

       這個函數(shù)定義在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中:

  1. class PackageManagerService extends IPackageManager.Stub {  
  2.     ......  
  3.   
  4.     public List<ResolveInfo> queryIntentActivities(Intent intent,  
  5.             String resolvedType, int flags) {  
  6.         ......  
  7.   
  8.         synchronized (mPackages) {  
  9.             String pkgName = intent.getPackage();  
  10.             if (pkgName == null) {  
  11.                 return (List<ResolveInfo>)mActivities.queryIntent(intent,  
  12.                         resolvedType, flags);  
  13.             }  
  14.   
  15.             ......  
  16.         }  
  17.   
  18.         ......  
  19.     }  
  20.   
  21.     ......  
  22. }  

        回憶前面一篇文章Android應(yīng)用程序安裝過程源代碼分析,,系統(tǒng)在前面的Step 8中啟動PackageManagerService時,會把系統(tǒng)中的應(yīng)用程序都解析一遍,,然后把解析得到的Activity都保存在mActivities變量中,,這里通過這個mActivities變量的queryIntent函數(shù)返回符合條件intent的Activity,這里要返回的便是Action類型為Intent.ACTION_MAIN,,并且Category類型為Intent.CATEGORY_LAUNCHER的Activity了,。

        回到Step 18中的 LoaderTask.loadAllAppsByBatch函數(shù)中,從queryIntentActivities函數(shù)調(diào)用處返回所要求的Activity后,,便調(diào)用函數(shù)tryGetCallbacks(oldCallbacks)得到一個返CallBack接口,,這個接口是由Launcher類實現(xiàn)的,接著調(diào)用這個接口的.bindAllApplications函數(shù)來進(jìn)一步操作,。注意,,這里又是通過消息來處理加載應(yīng)用程序的操作的。

        Step 20. Launcher.bindAllApplications

        這個函數(shù)定義在packages/apps/Launcher2/src/com/android/launcher2/Launcher.java文件中:

  1. public final class Launcher extends Activity  
  2.         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks, AllAppsView.Watcher {  
  3.     ......  
  4.   
  5.     private AllAppsView mAllAppsGrid;  
  6.   
  7.     ......  
  8.   
  9.     public void bindAllApplications(ArrayList<ApplicationInfo> apps) {  
  10.         mAllAppsGrid.setApps(apps);  
  11.     }  
  12.   
  13.     ......  
  14. }  
        這里的mAllAppsGrid是一個AllAppsView類型的變量,,它的實際類型一般就是AllApps2D了,。

        Step 21. AllApps2D.setApps

        這個函數(shù)定義在packages/apps/Launcher2/src/com/android/launcher2/AllApps2D.java文件中:

  1. public class AllApps2D  
  2.     extends RelativeLayout  
  3.     implements AllAppsView,  
  4.         AdapterView.OnItemClickListener,  
  5.         AdapterView.OnItemLongClickListener,  
  6.         View.OnKeyListener,  
  7.         DragSource {  
  8.   
  9.     ......  
  10.   
  11.     public void setApps(ArrayList<ApplicationInfo> list) {  
  12.         mAllAppsList.clear();  
  13.         addApps(list);  
  14.     }  
  15.   
  16.     public void addApps(ArrayList<ApplicationInfo> list) {  
  17.         final int N = list.size();  
  18.   
  19.         for (int i=0; i<N; i++) {  
  20.             final ApplicationInfo item = list.get(i);  
  21.             int index = Collections.binarySearch(mAllAppsList, item,  
  22.                 LauncherModel.APP_NAME_COMPARATOR);  
  23.             if (index < 0) {  
  24.                 index = -(index+1);  
  25.             }  
  26.             mAllAppsList.add(index, item);  
  27.         }  
  28.         mAppsAdapter.notifyDataSetChanged();  
  29.     }  
  30.   
  31.     ......  
  32. }  
        函數(shù)setApps首先清空mAllAppsList列表,然后調(diào)用addApps函數(shù)來為上一步得到的每一個應(yīng)用程序創(chuàng)建一個ApplicationInfo實例了,,有了這些ApplicationInfo實例之后,,就可以在桌面上展示系統(tǒng)中所有的應(yīng)用程序了。

        到了這里,,系統(tǒng)默認(rèn)的Home應(yīng)用程序Launcher就把PackageManagerService中的應(yīng)用程序加載進(jìn)來了,,當(dāng)我們在屏幕上點擊下面這個圖標(biāo)時,就會把剛才加載好的應(yīng)用程序以圖標(biāo)的形式展示出來了:

        點擊這個按鈕時,,便會響應(yīng)Launcher.onClick函數(shù):

  1. public final class Launcher extends Activity  
  2.         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks, AllAppsView.Watcher {  
  3.     ......  
  4.   
  5.     public void onClick(View v) {  
  6.         Object tag = v.getTag();  
  7.         if (tag instanceof ShortcutInfo) {  
  8.             ......  
  9.         } else if (tag instanceof FolderInfo) {  
  10.             ......  
  11.         } else if (v == mHandleView) {  
  12.             if (isAllAppsVisible()) {  
  13.                 ......  
  14.             } else {  
  15.                 showAllApps(true);  
  16.             }  
  17.         }  
  18.     }  
  19.   
  20.     ......  
  21. }  
        接著就會調(diào)用showAllApps函數(shù)顯示應(yīng)用程序圖標(biāo):

  1. public final class Launcher extends Activity  
  2.         implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks, AllAppsView.Watcher {  
  3.     ......  
  4.   
  5.     void showAllApps(boolean animated) {  
  6.         mAllAppsGrid.zoom(1.0f, animated);  
  7.   
  8.         ((View) mAllAppsGrid).setFocusable(true);  
  9.         ((View) mAllAppsGrid).requestFocus();  
  10.   
  11.         // TODO: fade these two too   
  12.         mDeleteZone.setVisibility(View.GONE);  
  13.     }  
  14.   
  15.     ......  
  16. }  
        這樣我們就可以看到系統(tǒng)中的應(yīng)用程序了:



        當(dāng)點擊上面的這些應(yīng)用程序圖標(biāo)時,,便會響應(yīng)AllApps2D.onItemClick函數(shù):

  1. public class AllApps2D  
  2.     extends RelativeLayout  
  3.     implements AllAppsView,  
  4.         AdapterView.OnItemClickListener,  
  5.         AdapterView.OnItemLongClickListener,  
  6.         View.OnKeyListener,  
  7.         DragSource {  
  8.   
  9.     ......  
  10.   
  11.     public void onItemClick(AdapterView parent, View v, int position, long id) {  
  12.         ApplicationInfo app = (ApplicationInfo) parent.getItemAtPosition(position);  
  13.         mLauncher.startActivitySafely(app.intent, app);  
  14.     }  
  15.   
  16.   
  17.     ......  
  18. }<span style="font-family:Arial, Verdana, sans-serif;"><span style="white-space: normal;">  
  19. </span></span>  

        這里的成員變量mLauncher的類型為Launcher,于是就調(diào)用Launcher.startActivitySafely函數(shù)來啟動應(yīng)用程序了,,這個過程具體可以參考Android應(yīng)用程序啟動過程源代碼分析一文,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多