zoukankan      html  css  js  c++  java
  • Android系统默认Home应用程序(Launcher)的启动过程源码分析

            在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还须要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应用程序就是Launcher了,本文将详细分析Launcher应用程序的启动过程。

            Android系统的Home应用程序Launcher是由ActivityManagerService启动的,而ActivityManagerService和PackageManagerService一样,都是在开机时由SystemServer组件启动的,SystemServer组件首先是启动ePackageManagerServic,由它来负责安装系统的应用程序,详细能够參考前面一篇文章Android应用程序安装过程源码分析,系统中的应用程序安装好了以后,SystemServer组件接下来就要通过ActivityManagerService来启动Home应用程序Launcher了,Launcher在启动的时候便会通过PackageManagerServic把系统中已经安装好的应用程序以快捷图标的形式展示在桌面上,这样用户就能够使用这些应用程序了,整个步骤例如以下图所看到的:


    点击查看大图

            以下详细分析每个步骤。

            Step 1. SystemServer.main

            这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件里,详细能够參考前面一篇文章Android应用程序安装过程源码分析的Step 1。

            Step 2. SystemServer.init1

            这个函数是一个JNI方法,实如今 frameworks/base/services/jni/com_android_server_SystemServer.cpp文件里,详细能够參考前面一篇文章Android应用程序安装过程源码分析的Step 2。

            Step 3. libsystem_server.system_init

            函数system_init实如今libsystem_server库中,源码位于frameworks/base/cmds/system_server/library/system_init.cpp文件里,详细能够參考前面一篇文章Android应用程序安装过程源码分析的Step 3。

            Step 4. AndroidRuntime.callStatic

            这个函数定义在frameworks/base/core/jni/AndroidRuntime.cpp文件里,详细能够參考前面一篇文章Android应用程序安装过程源码分析的Step 4。

            Step 5. SystemServer.init2

            这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件里,详细能够參考前面一篇文章Android应用程序安装过程源码分析的Step 5。

            Step 6. ServerThread.run

            这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件里,详细能够參考前面一篇文章Android应用程序安装过程源码分析的Step 6。

            Step 7. ActivityManagerService.main

            这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerServcie.java文件里:

    public final class ActivityManagerService extends ActivityManagerNative
    		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    	......
    
    	public static final Context main(int factoryTest) {
    		AThread thr = new AThread();
    		thr.start();
    
    		synchronized (thr) {
    			while (thr.mService == null) {
    				try {
    					thr.wait();
    				} catch (InterruptedException e) {
    				}
    			}
    		}
    
    		ActivityManagerService m = thr.mService;
    		mSelf = m;
    		ActivityThread at = ActivityThread.systemMain();
    		mSystemThread = at;
    		Context context = at.getSystemContext();
    		m.mContext = context;
    		m.mFactoryTest = factoryTest;
    		m.mMainStack = new ActivityStack(m, context, true);
    
    		m.mBatteryStatsService.publish(context);
    		m.mUsageStatsService.publish(context);
    
    		synchronized (thr) {
    			thr.mReady = true;
    			thr.notifyAll();
    		}
    
    		m.startRunning(null, null, null, null);
    
    		return context;
    	}
    
    	......
    }
            这个函数首先通过AThread线程对象来内部创建了一个ActivityManagerService实例,然后将这个实例保存其成员变量mService中,接着又把这个ActivityManagerService实例保存在ActivityManagerService类的静态成员变量mSelf中,最后初始化其他成员变量,就结束了。

            Step 8. PackageManagerService.main

            这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件里,详细能够參考前面一篇文章Android应用程序安装过程源码分析的Step 7。运行完这一步之后,系统中的应用程序的全部信息都保存在PackageManagerService中了,后面Home应用程序Launcher启动起来后,就会把PackageManagerService中的应用程序信息取出来,然后以快捷图标的形式展示在桌面上,后面我们将会看到这个过程。

            Step 9. ActivityManagerService.setSystemProcess

            这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerServcie.java文件里:

    public final class ActivityManagerService extends ActivityManagerNative
    		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    	......
    
    	public static void setSystemProcess() {
    		try {
    			ActivityManagerService m = mSelf;
    
    			ServiceManager.addService("activity", m);
    			ServiceManager.addService("meminfo", new MemBinder(m));
    			if (MONITOR_CPU_USAGE) {
    				ServiceManager.addService("cpuinfo", new CpuBinder(m));
    			}
    			ServiceManager.addService("permission", new PermissionController(m));
    
    			ApplicationInfo info =
    				mSelf.mContext.getPackageManager().getApplicationInfo(
    				"android", STOCK_PM_FLAGS);
    			mSystemThread.installSystemApplicationInfo(info);
    
    			synchronized (mSelf) {
    				ProcessRecord app = mSelf.newProcessRecordLocked(
    					mSystemThread.getApplicationThread(), info,
    					info.processName);
    				app.persistent = true;
    				app.pid = MY_PID;
    				app.maxAdj = SYSTEM_ADJ;
    				mSelf.mProcessNames.put(app.processName, app.info.uid, app);
    				synchronized (mSelf.mPidsSelfLocked) {
    					mSelf.mPidsSelfLocked.put(app.pid, app);
    				}
    				mSelf.updateLruProcessLocked(app, true, true);
    			}
    		} catch (PackageManager.NameNotFoundException e) {
    			throw new RuntimeException(
    				"Unable to find android system package", e);
    		}
    	}
    	......
    }
            这个函数首先是将这个ActivityManagerService实例加入到ServiceManager中去托管,这样其他地方就能够通过ServiceManager.getService接口来訪问这个全局唯一的ActivityManagerService实例了,接着又通过调用mSystemThread.installSystemApplicationInfo函数来把应用程序框架层以下的android包载入进来 ,这里的mSystemThread是一个ActivityThread类型的实例变量,它是在上面的Step 7中创建的,后面就是一些其他的初始化工作了。

            Step 10.  ActivityManagerService.systemReady

            这个函数是在上面的Step 6中的ServerThread.run函数在将系统中的一系列服务都初始化完成之后才调用的,它定义在frameworks/base/services/java/com/android/server/am/ActivityManagerServcie.java文件里:

    public final class ActivityManagerService extends ActivityManagerNative
    		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    	......
    
    	public void systemReady(final Runnable goingCallback) {
    		......
    
    		synchronized (this) {
    			......
    
    			mMainStack.resumeTopActivityLocked(null);
    		}
    	}
    
    	......
    }
            这个函数的内容比較多,这里省去无关的部分,主要关心启动Home应用程序的逻辑,这里就是通过mMainStack.resumeTopActivityLocked函数来启动Home应用程序的了,这里的mMainStack是一个ActivityStack类型的实例变量。

            Step 11. ActivityStack.resumeTopActivityLocked

            这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件里:

    public class ActivityStack {
    	......
    
    	final boolean resumeTopActivityLocked(ActivityRecord prev) {
    		// Find the first activity that is not finishing.
    		ActivityRecord next = topRunningActivityLocked(null);
    
    		......
    
    		if (next == null) {
    			// There are no more activities!  Let's just start up the
    			// Launcher...
    			if (mMainStack) {
    				return mService.startHomeActivityLocked();
    			}
    		}
    
    		......
    	}
    
    	......
    }
            这里调用函数topRunningActivityLocked返回的是当前系统Activity堆栈最顶端的Activity,因为此时还没有Activity被启动过,因此,返回值为null,即next变量的值为null,于是就调用mService.startHomeActivityLocked语句,这里的mService就是前面在Step 7中创建的ActivityManagerService实例了。

            Step 12. ActivityManagerService.startHomeActivityLocked

            这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerServcie.java文件里:

    public final class ActivityManagerService extends ActivityManagerNative
    		implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    	......
    
    	boolean startHomeActivityLocked() {
    		......
    
    		Intent intent = new Intent(
    			mTopAction,
    			mTopData != null ? Uri.parse(mTopData) : null);
    		intent.setComponent(mTopComponent);
    		if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
    			intent.addCategory(Intent.CATEGORY_HOME);
    		}
    		ActivityInfo aInfo =
    			intent.resolveActivityInfo(mContext.getPackageManager(),
    			STOCK_PM_FLAGS);
    		if (aInfo != null) {
    			intent.setComponent(new ComponentName(
    				aInfo.applicationInfo.packageName, aInfo.name));
    			// Don't do this if the home app is currently being
    			// instrumented.
    			ProcessRecord app = getProcessRecordLocked(aInfo.processName,
    				aInfo.applicationInfo.uid);
    			if (app == null || app.instrumentationClass == null) {
    				intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
    				mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
    					null, null, 0, 0, 0, false, false);
    			}
    		}
    
    		return true;
    	}
    
    	......
    }
            函数首先创建一个CATEGORY_HOME类型的Intent,然后通过Intent.resolveActivityInfo函数向PackageManagerService查询Category类型为HOME的Activity,这里我们如果仅仅有系统自带的Launcher应用程序注冊了HOME类型的Activity(见packages/apps/Launcher2/AndroidManifest.xml文件):

    <manifest
        xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.launcher"
        android:sharedUserId="@string/sharedUserId"
    	>
    
        ......
    
    	<application
    	    android:name="com.android.launcher2.LauncherApplication"
    	    android:process="@string/process"
    	    android:label="@string/application_name"
    	    android:icon="@drawable/ic_launcher_home">
    
    		<activity
    			android:name="com.android.launcher2.Launcher"
    			android:launchMode="singleTask"
    			android:clearTaskOnLaunch="true"
    			android:stateNotNeeded="true"
    			android:theme="@style/Theme"
    			android:screenOrientation="nosensor"
    			android:windowSoftInputMode="stateUnspecified|adjustPan">
    			<intent-filter>
    				<action android:name="android.intent.action.MAIN" />
    				<category android:name="android.intent.category.HOME" />
    				<category android:name="android.intent.category.DEFAULT" />
    				<category android:name="android.intent.category.MONKEY"/>
    				</intent-filter>
    		</activity>
    
    		......
    	</application>
    </manifest>

            因此,这里就返回com.android.launcher2.Launcher这个Activity了。因为是第一次启动这个Activity,接下来调用函数getProcessRecordLocked返回来的ProcessRecord值为null,于是,就调用mMainStack.startActivityLocked函数启动com.android.launcher2.Launcher这个Activity了,这里的mMainStack是一个ActivityStack类型的成员变量。

            Step 13.  ActivityStack.startActivityLocked

            这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件里,详细能够參考Android应用程序启动过程源码分析一文,这里就不详述了,在我们这个场景中,调用这个函数的最后结果就是把com.android.launcher2.Launcher启动起来,接着调用它的onCreate函数。

            Step 14. Launcher.onCreate

            这个函数定义在packages/apps/Launcher2/src/com/android/launcher2/Launcher.java文件里:

    public final class Launcher extends Activity
    		implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks, AllAppsView.Watcher {
    	......
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		......
    
    		if (!mRestoring) {
    			mModel.startLoader(this, true);
    		}
    
    		......
    	}
    
    	......
    }
            这里的mModel是一个LauncherModel类型的成员变量,这里通过调用它的startLoader成员函数来运行加应用程序的操作。

            Step 15. LauncherModel.startLoader

            这个函数定义在packages/apps/Launcher2/src/com/android/launcher2/LauncherModel.java文件里:

    public class LauncherModel extends BroadcastReceiver {
    	......
    
    	public void startLoader(Context context, boolean isLaunching) {
    		......
    
                    synchronized (mLock) {
                         ......
    
                         // Don't bother to start the thread if we know it's not going to do anything
                         if (mCallbacks != null && mCallbacks.get() != null) {
                             // If there is already one running, tell it to stop.
                             LoaderTask oldTask = mLoaderTask;
                             if (oldTask != null) {
                                 if (oldTask.isLaunching()) {
                                     // don't downgrade isLaunching if we're already running
                                     isLaunching = true;
                                 }
                                 oldTask.stopLocked();
    		         }
    		         mLoaderTask = new LoaderTask(context, isLaunching);
    		         sWorker.post(mLoaderTask);
    	            }
    	       }
    	}
    
    	......
    }
            这里不是直接载入应用程序,而是把载入应用程序的操作作为一个消息来处理。这里的sWorker是一个Handler,通过它的post方式把一个消息放在消息队列中去,然后系统就会调用传进去的參数mLoaderTask的run函数来处理这个消息,这个mLoaderTask是LoaderTask类型的实例,于是,以下就会运行LoaderTask类的run函数了。

            Step 16. LoaderTask.run

            这个函数定义在packages/apps/Launcher2/src/com/android/launcher2/LauncherModel.java文件里:

    public class LauncherModel extends BroadcastReceiver {
    	......
    
    	private class LoaderTask implements Runnable {
    		......
    
    		public void run() {
    			......
    
    			keep_running: {
    				......
    
    				// second step
    				if (loadWorkspaceFirst) {
    					......
    					loadAndBindAllApps();
    				} else {
    					......
    				}
    
    				......
    			}
    
    			......
    		}
    
    		......
    	}
    
    	......
    }
            这里调用loadAndBindAllApps成员函数来进一步操作。

            Step 17. LoaderTask.loadAndBindAllApps
            这个函数定义在packages/apps/Launcher2/src/com/android/launcher2/LauncherModel.java文件里:

    public class LauncherModel extends BroadcastReceiver {
    	......
    
    	private class LoaderTask implements Runnable {
    		......
    
    		private void loadAndBindAllApps() {
    			......
    
    			if (!mAllAppsLoaded) {
    				loadAllAppsByBatch();
    				if (mStopped) {
    					return;
    				}
    				mAllAppsLoaded = true;
    			} else {
    				onlyBindAllApps();
    			}
    		}
    
    
    		......
    	}
    
    	......
    }
            因为还没有载入过应用程序,这里的mAllAppsLoaded为false,于是就继续调用loadAllAppsByBatch函数来进一步操作了。

            Step 18. LoaderTask.loadAllAppsByBatch
            这个函数定义在packages/apps/Launcher2/src/com/android/launcher2/LauncherModel.java文件里:

    public class LauncherModel extends BroadcastReceiver {
    	......
    
    	private class LoaderTask implements Runnable {
    		......
    
    		private void loadAllAppsByBatch() {	
    			......
    
    			final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
    			mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
    
    			final PackageManager packageManager = mContext.getPackageManager();
    			List<ResolveInfo> apps = null;
    
    			int N = Integer.MAX_VALUE;
    
    			int startIndex;
    			int i=0;
    			int batchSize = -1;
    			while (i < N && !mStopped) {
    				if (i == 0) {
    					mAllAppsList.clear();
    					......
    					apps = packageManager.queryIntentActivities(mainIntent, 0);
    					
    					......
    
    					N = apps.size();
    					
    					......
    
    					if (mBatchSize == 0) {
    						batchSize = N;
    					} else {
    						batchSize = mBatchSize;
    					}
    
    					......
    
    					Collections.sort(apps,
    						new ResolveInfo.DisplayNameComparator(packageManager));
    				}
    
    				startIndex = i;
    				for (int j=0; i<N && j<batchSize; j++) {
    					// This builds the icon bitmaps.
    					mAllAppsList.add(new ApplicationInfo(apps.get(i), mIconCache));
    					i++;
    				}
    
    				final boolean first = i <= batchSize;
    				final Callbacks callbacks = tryGetCallbacks(oldCallbacks);
    				final ArrayList<ApplicationInfo> added = mAllAppsList.added;
    				mAllAppsList.added = new ArrayList<ApplicationInfo>();
    			
    				mHandler.post(new Runnable() {
    					public void run() {
    						final long t = SystemClock.uptimeMillis();
    						if (callbacks != null) {
    							if (first) {
    								callbacks.bindAllApplications(added);
    							} else {
    								callbacks.bindAppsAdded(added);
    							}
    							......
    						} else {
    							......
    						}
    					}
    				});
    
    				......
    			}
    
    			......
    		}
    
    		......
    	}
    
    	......
    }
            函数首先构造一个CATEGORY_LAUNCHER类型的Intent:

        final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
            接着从mContext变量中获得PackageManagerService的接口:

        final PackageManager packageManager = mContext.getPackageManager();

           下一步就是通过这个PackageManagerService.queryIntentActivities接口来取回全部Action类型为Intent.ACTION_MAIN,而且Category类型为Intent.CATEGORY_LAUNCHER的Activity了。

           我们先进入到PackageManagerService.queryIntentActivities函数中看看是怎样获得这些Activity的,然后再回到这个函数中来看其余操作。

           Step 19. PackageManagerService.queryIntentActivities

           这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件里:

    class PackageManagerService extends IPackageManager.Stub {
    	......
    
    	public List<ResolveInfo> queryIntentActivities(Intent intent,
    			String resolvedType, int flags) {
    		......
    
    		synchronized (mPackages) {
    			String pkgName = intent.getPackage();
    			if (pkgName == null) {
    				return (List<ResolveInfo>)mActivities.queryIntent(intent,
    						resolvedType, flags);
    			}
    
    			......
    		}
    
    		......
    	}
    
    	......
    }

            回顾前面一篇文章Android应用程序安装过程源码分析,系统在前面的Step 8中启动PackageManagerService时,会把系统中的应用程序都解析一遍,然后把解析得到的Activity都保存在mActivities变量中,这里通过这个mActivities变量的queryIntent函数返回符合条件intent的Activity,这里要返回的便是Action类型为Intent.ACTION_MAIN,而且Category类型为Intent.CATEGORY_LAUNCHER的Activity了。

            回到Step 18中的 LoaderTask.loadAllAppsByBatch函数中,从queryIntentActivities函数调用处返回所要求的Activity后,便调用函数tryGetCallbacks(oldCallbacks)得到一个返CallBack接口,这个接口是由Launcher类实现的,接着调用这个接口的.bindAllApplications函数来进一步操作。注意,这里又是通过消息来处理载入应用程序的操作的。

            Step 20. Launcher.bindAllApplications

            这个函数定义在packages/apps/Launcher2/src/com/android/launcher2/Launcher.java文件里:

    public final class Launcher extends Activity
    		implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks, AllAppsView.Watcher {
    	......
    
    	private AllAppsView mAllAppsGrid;
    
    	......
    
    	public void bindAllApplications(ArrayList<ApplicationInfo> apps) {
    		mAllAppsGrid.setApps(apps);
    	}
    
    	......
    }
            这里的mAllAppsGrid是一个AllAppsView类型的变量,它的实际类型一般就是AllApps2D了。

            Step 21. AllApps2D.setApps

            这个函数定义在packages/apps/Launcher2/src/com/android/launcher2/AllApps2D.java文件里:

    public class AllApps2D
    	extends RelativeLayout
    	implements AllAppsView,
    		AdapterView.OnItemClickListener,
    		AdapterView.OnItemLongClickListener,
    		View.OnKeyListener,
    		DragSource {
    
    	......
    
    	public void setApps(ArrayList<ApplicationInfo> list) {
    		mAllAppsList.clear();
    		addApps(list);
    	}
    
    	public void addApps(ArrayList<ApplicationInfo> list) {
    		final int N = list.size();
    
    		for (int i=0; i<N; i++) {
    			final ApplicationInfo item = list.get(i);
    			int index = Collections.binarySearch(mAllAppsList, item,
    				LauncherModel.APP_NAME_COMPARATOR);
    			if (index < 0) {
    				index = -(index+1);
    			}
    			mAllAppsList.add(index, item);
    		}
    		mAppsAdapter.notifyDataSetChanged();
    	}
    
    	......
    }
            函数setApps首先清空mAllAppsList列表,然后调用addApps函数来为上一步得到的每个应用程序创建一个ApplicationInfo实例了,有了这些ApplicationInfo实例之后,就能够在桌面上展示系统中全部的应用程序了。

            到了这里,系统默认的Home应用程序Launcher就把PackageManagerService中的应用程序载入进来了,当我们在屏幕上点击以下这个图标时,就会把刚才载入好的应用程序以图标的形式展示出来了:

            点击这个button时,便会响应Launcher.onClick函数:

    public final class Launcher extends Activity
    		implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks, AllAppsView.Watcher {
    	......
    
    	public void onClick(View v) {
    		Object tag = v.getTag();
    		if (tag instanceof ShortcutInfo) {
    			......
    		} else if (tag instanceof FolderInfo) {
    			......
    		} else if (v == mHandleView) {
    			if (isAllAppsVisible()) {
    				......
    			} else {
    				showAllApps(true);
    			}
    		}
    	}
    
    	......
    }
            接着就会调用showAllApps函数显示应用程序图标:

    public final class Launcher extends Activity
    		implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks, AllAppsView.Watcher {
    	......
    
    	void showAllApps(boolean animated) {
    		mAllAppsGrid.zoom(1.0f, animated);
    
    		((View) mAllAppsGrid).setFocusable(true);
    		((View) mAllAppsGrid).requestFocus();
    
    		// TODO: fade these two too
    		mDeleteZone.setVisibility(View.GONE);
    	}
    
    	......
    }
            这样我们就能够看到系统中的应用程序了:



            当点击上面的这些应用程序图标时,便会响应AllApps2D.onItemClick函数:

    public class AllApps2D
    	extends RelativeLayout
    	implements AllAppsView,
    		AdapterView.OnItemClickListener,
    		AdapterView.OnItemLongClickListener,
    		View.OnKeyListener,
    		DragSource {
    
    	......
    
    	public void onItemClick(AdapterView parent, View v, int position, long id) {
    		ApplicationInfo app = (ApplicationInfo) parent.getItemAtPosition(position);
    		mLauncher.startActivitySafely(app.intent, app);
    	}
    
    
    	......
    }
    

            这里的成员变量mLauncher的类型为Launcher,于是就调用Launcher.startActivitySafely函数来启动应用程序了,这个过程详细能够參考Android应用程序启动过程源码分析一文。

    老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注!

  • 相关阅读:
    欧拉回路 定理
    UESTC 1087 【二分查找】
    POJ 3159 【朴素的差分约束】
    ZOJ 1232 【灵活运用FLOYD】 【图DP】
    POJ 3013 【需要一点点思维...】【乘法分配率】
    POJ 2502 【思维是朴素的最短路 卡输入和建图】
    POJ 2240 【这题貌似可以直接FLOYD 屌丝用SPFA通过枚举找正权值环 顺便学了下map】
    POJ 1860【求解是否存在权值为正的环 屌丝做的第一道权值需要计算的题 想喊一声SPFA万岁】
    POJ 1797 【一种叫做最大生成树的很有趣的贪心】【也可以用dij的变形思想~】
    js 实现slider封装
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4271892.html
Copyright © 2011-2022 走看看