編輯:關於Android編程
之前講Android的View的繪制原理和流程的時候,講到過在Android調用setContentView之後,Android調用了一個prepreTravle的方法,這裡面就提到了ActivityManagerService。
ActivityManagerService提供的主要功能:
(1)統一調度各應用程序的Activity
(2)內存管理
(3)進程管理
上一篇我們分析Android啟動過程的文章中我們分析到了SystemServer,當時我們只是簡單的描述了下,我們還是來看一張啟動的流程圖,

System Server代碼位於://frameworks\base\services\java\com\android\server\SystemServer.java
我們來看一段啟動的代碼:
private void run() {
// 准備SystemServer運行環境:設置線程優先級,創建主線層Looper,ActivityThread和SystemContext
android.os.Process.setThreadPriority();
Looper.prepareMainLooper();
// 創建systemserver上進程的ActivityThread和SystemContext
createSystemContext();
// 增加SystemServiceManager:統一管理system services的創建,啟動和生命周期,多用戶切換
mSystemServiceManager = new SystemServiceManager(mSystemContext);
// Start services.
// 1.創建AMS
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
// Start the Power Manager service
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
// Start the package manager service
mPackageManagerService = PackageManagerService.main();
// 2.將SystemServer進程可加到AMS中調度管理
mActivityManagerService.setSystemProcess();
// 3.將相關provider運行在systemserver進程中:SettingsProvider
mActivityManagerService.installSystemProviders();
//
final Watchdog watchdog = Watchdog.getInstance();
watchdog.init(context, mActivityManagerService);
// Start Window Manager
wm = WindowManagerService.main();
// 4.直接保存wms對象,與WMS交互
mActivityManagerService.setWindowManager(wm);
// 5.通過WMS 彈出“正在啟動應用”框
// R.string.android_upgrading_starting_apps
ActivityManagerNative.getDefault().showBootMessage();
// 6. AMS作為Framework核心,做好准備就緒後就開始啟動應用層,和對AMS有依賴的服務
mActivityManagerService.systemReady(new Runnable(){
//啟動SystemUI
startSystemUi(context);
//啟動WatchDog監控核心服務狀態
Watchdog.getInstance().start();
//
mmsServiceF.systemRunning();
});
// Loop forever.
Looper.loop();
}
上面的6個步驟就是SystemServer中關於AMS的調用,完成AMS的創建和系統的初始化,以及與WMS交互等流程。
一、ActivityManagerService 創建過程
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
通過SystemServiceManager這樣一個模板類來創建運行在SystemServer中的Framework服務。並將創建的服務統一保存在隊列管理。
public ActivityManagerService(Context systemContext) {
// 1.系統Context 和 ActivityThread (將systemserver進程作為應用進程管理)
mContext = systemContext;
mFactoryTest = FactoryTest.getMode();
mSystemThread = ActivityThread.currentActivityThread();
// 2.AMS工作的線程和Handler,處理顯示相關的UiHandler ---》知識點HandlerThread和Handler
mHandlerThread = new ServiceThread(TAG,
android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
mUiHandler = new UiHandler();
// 3. 廣播隊列BroadcastQueue初始化:前台廣播隊列和後台廣播隊列
mFgBroadcastQueue = new BroadcastQueue(this, mHandler,"foreground", BROADCAST_FG_TIMEOUT, false);
mBgBroadcastQueue = new BroadcastQueue(this, mHandler,"background", BROADCAST_BG_TIMEOUT, true);
mBroadcastQueues[0] = mFgBroadcastQueue;
mBroadcastQueues[1] = mBgBroadcastQueue;
// 4. Service 和 Provider 管理
mServices = new ActiveServices(this);
mProviderMap = new ProviderMap(this);
// 5.系統數據存放目錄:/data/system/
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
systemDir.mkdirs();
// 電池狀態信息,進程狀態 和 應用權限管理
mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
// 6.多用戶管理
mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
mUserLru.add(UserHandle.USER_OWNER);
updateStartedUserArrayLocked();
// 7.最近任務,Activity,Task管理
mRecentTasks = new RecentTasks(this);
mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
// 創建一個新線程,用於監控和定時更新系統CPU信息,30分鐘更新一次CPU和電池信息
mProcessCpuTracker.init();
mProcessCpuThread = new Thread("CpuTracker") {}
// 加入Watchdog監控起來
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
}
public void setSystemProcess() {
// 將服務加入到ServiceManager中
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
// 設置application info LoadedApkinfo 有關 framework-res.apk
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS);
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
//給SystemServer進程創建ProcessRecord,adj值,就是將SystemServer進程加入到AMS進程管理機制中,跟應用進程一致
synchronized (this) {
ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
app.persistent = true;
app.pid = MY_PID;
app.maxAdj = ProcessList.SYSTEM_ADJ;
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.put(app.pid, app);
}
updateLruProcessLocked(app, false, null);
updateOomAdjLocked();
}
}
這一步就是給SystemServer進程創建ProcessRecord,adj值,就是將SystemServer進程加入到AMS進程管理。
取出進程名為"system",user_id為SYSTEM_UID的進程信息 ,生成運行在system進程中的providerInfo,並交給上下文的Provider。這段代碼的任務就是查詢與安裝Content Provider並且發布,其中查詢出來的provider為SettingsProvider
public final void installSystemProviders() {
List providers;
synchronized (this) {
//取出進程名為"system",user_id為SYSTEM_UID的進程信息
ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
//生成運行在system進程中的providerInfo,表示一個Content Provider。
providers = generateApplicationProvidersLocked(app);
if (providers != null) {
for (int i=providers.size()-1; i>=0; i--) {
ProviderInfo pi = (ProviderInfo)providers.get(i);
//過濾掉非系統apk
if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
Slog.w(TAG, "Not installing system proc provider " + pi.name
+ ": not system .apk");
providers.remove(i);
}
}
}
}
if (providers != null) {
//安裝provider
mSystemThread.installSystemProviders(providers);
}
//監聽Settings數據庫變化。
mCoreSettingsObserver = new CoreSettingsObserver(this);
//mUsageStatsService.monitorPackages();
mActivityManagerService.systemReady();
發送ACTION_PRE_BOOT_COMPLETE方法,清理啟動的persistent進程,讀取Settings配置,運行runnable接口,啟動SystemUI,啟動persistent應用程序,啟動home,發送ACTION_BOOT_COMPLETE廣播
public void systemReady(final Runnable goingCallback) {
synchronized(this) {
if (mSystemReady) {
goingCallback.run();
}
……
// 1.升級相關處理:發送PRE_BOOT_COMPLETED廣播 等待升級處理完成才能繼續
// Check to see if there are any update receivers to run.
if (!mDidUpdate) {
// 等待升級完成,否則直接返回
if (mWaitingUpdate) {
return;
}
// 發送PRE_BOOT_COMPLETED廣播
final ArrayList doneReceivers = new ArrayList();
mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
// 等待所有接收PRE_BOOT_COMPLETED廣播者處理完畢
public void run() {
synchronized (ActivityManagerService.this) {
mDidUpdate = true;
}
showBootMessage(mContext.getText(
R.string.android_upgrading_complete),
false);
// 將系統版本號和處理過的廣播寫入文件:/data/system/called_pre_boots.dat文件
writeLastDonePreBootReceivers(doneReceivers);
// 繼續systemReady流程
systemReady(goingCallback);
}
}, doneReceivers, UserHandle.USER_OWNER);
if (mWaitingUpdate) {
return;
}
mDidUpdate = true;
}
mSystemReady = true;
}
// 2. 收集已經啟動的進程並殺死,除過persistent常駐進程
ArrayList procsToKill = null;
synchronized(mPidsSelfLocked) {
for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
ProcessRecord proc = mPidsSelfLocked.valueAt(i);
if (!isAllowedWhileBooting(proc.info)){
if (procsToKill == null) {
procsToKill = new ArrayList();
}
procsToKill.add(proc);
}
}
}
synchronized(this) {
if (procsToKill != null) {
for (int i=procsToKill.size()-1; i>=0; i--) {
ProcessRecord proc = procsToKill.get(i);
Slog.i(TAG, "Removing system update proc: " + proc);
removeProcessLocked(proc, true, false, "system update done");
}
}
// Now that we have cleaned up any update processes, we
// are ready to start launching real processes and know that
// we won't trample on them any more.
mProcessesReady = true;
}
// 3.系統准備好後回調傳入的Runnable:
if (goingCallback != null) goingCallback.run();
// 4. 發送賬戶啟動的廣播,涉及多用戶
long ident = Binder.clearCallingIdentity();
Intent intent = new Intent(Intent.ACTION_USER_STARTED);
broadcastIntentLocked(intent);
intent = new Intent(Intent.ACTION_USER_STARTING);
broadcastIntentLocked(intent);
Binder.restoreCallingIdentity(ident);
// 5. 啟動桌面Home Activity
mBooting = true;
startHomeActivityLocked(mCurrentUserId, "systemReady");
mStackSupervisor.resumeTopActivitiesLocked();
}
Android4.4 應用分析——修改Launcher3應用以適應單屏壁紙
Launcher3壁紙的規格默認是:壁紙高度=屏幕高度,壁紙寬帶=屏幕寬度*2倍 Android4.4的壁紙信息存放在/data/system/users/0/目錄下,W
Android 仿qq上傳頭像(一)
這麼長時間沒寫博客感覺手都要生了啊,最近因為工作的關系來到了上海,目前還算穩定,所以抓緊時間寫篇博客壓壓驚。標題早已經看穿一切,這次我們來模仿一下
Android控件之GridView用法實例分析
本文實例講述了Android控件之GridView用法。分享給大家供大家參考。具體如下:GridView是一項顯示二維的viewgroup,可滾動的網格。一般用來顯示多張
listview改變字體大小實例講解
效果:點擊字體,字體變大 主要利用的getView()方法和setOnItemClickListener()方法 ListText.java 復制代碼 代碼如下: pac