編輯:關於Android編程
本文從SystemServer的main函數開始研究。
/*** SystemServer.java ***/ public static void main(String[] args) { new SystemServer().run(); } public SystemServer() { mFactoryTestMode = FactoryTest.getMode(); }SystemServer的初始化,只是簡單的檢查了一下是否處於工廠測試模式。
/*** SystemServer.java ***/ private void run() { //如果系統時間早於1970,則設置系統時間為1970年。 if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { Slog.w(TAG, "System clock is before 1970; setting to 1970."); SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); } //設置區域,語言等選項 if (!SystemProperties.get("persist.sys.language").isEmpty()) { final String languageTag = Locale.getDefault().toLanguageTag(); SystemProperties.set("persist.sys.locale", languageTag); SystemProperties.set("persist.sys.language", ""); SystemProperties.set("persist.sys.country", ""); SystemProperties.set("persist.sys.localevar", ""); } // Here we go! Slog.i(TAG, "Entered the Android system server!"); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis()); //虛擬機使用 dvm 或 art。參考“Android ART運行時無縫替換Dalvik虛擬機的過程分析”一文 SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary()); //啟動采樣分析,分析性能時使用 if (SamplingProfilerIntegration.isEnabled()) { SamplingProfilerIntegration.start(); mProfilerSnapshotTimer = new Timer(); mProfilerSnapshotTimer.schedule(new TimerTask() { @Override public void run() { SamplingProfilerIntegration.writeSnapshot("system_server", null); } }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL); } //清除vm內存增長上限,由於啟動過程需要較多的虛擬機內存空間 VMRuntime.getRuntime().clearGrowthLimit(); //設置堆棧利用率。GC後會重新計算堆棧空間大小。 VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); //針對部分設備依賴於運行時就產生指紋信息,因此需要在開機完成前已經定義 Build.ensureFingerprintProperty(); //訪問環境變量前,需要明確地指定用戶 Environment.setUserRequired(true); //確保當前系統進程的binder調用,總是運行在前台優先級(foreground priority) BinderInternal.disableBackgroundScheduling(true); android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false); Looper.prepareMainLooper(); // Initialize native services. //frameworks/base/services/Android.mk //LOCAL_MODULE:= libandroid_servers System.loadLibrary("android_servers"); //檢測上次關機過程是否失敗,該方法可能不會返回 performPendingShutdown(); //初始化系統上下文 createSystemContext(); //創建系統服務管理 mSystemServiceManager = new SystemServiceManager(mSystemContext); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); //啟動各種系統服務 try { startBootstrapServices(); //啟動引導服務 startCoreServices(); //啟動核心服務 startOtherServices(); //啟動其他服務 } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } //用於debug版本,將log事件不斷循環地輸出到dropbox(用於分析) if (StrictMode.conditionallyEnableDebugLogging()) { Slog.i(TAG, "Enabled StrictMode for system server main thread."); } //一直循環執行 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }去掉一些初始化設置,簡化後的run函數如下:
/*** SystemServer.java ***/ private void run() { Looper.prepareMainLooper(); //初始化系統上下文 createSystemContext(); //創建系統服務管理 mSystemServiceManager = new SystemServiceManager(mSystemContext); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); //啟動各種系統服務 try { startBootstrapServices(); //啟動引導服務 startCoreServices(); //啟動核心服務 startOtherServices(); //啟動其他服務 } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }簡單來看,SystemServer啟動時主要做了以下幾件事:
/*** SystemServer.java ***/ private void createSystemContext() { ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar); }1.創建ActivityThread
/*** ActivityThread.java ***/ public static ActivityThread systemMain() { //對於低內存的設備,禁用硬件加速 if (!ActivityManager.isHighEndGfx()) { HardwareRenderer.disable(true); } else { HardwareRenderer.enableForegroundTrimming(); } ActivityThread thread = new ActivityThread(); thread.attach(true); return thread; } ActivityThread() { //使用單例模式獲得一個ResourcesManager實例 mResourcesManager = ResourcesManager.getInstance(); }
/*** ActivityThread.java ***/ private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; if (!system) { ... } else { //設置SystemServer進程在DDMS中顯示的名字為"system_process" //如不設置,則顯示"?",無法調試該進程。app一般顯示包名。 android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId()); try { mInstrumentation = new Instrumentation(); //首先通過getSystemContext()創建系統上下文,然後創建應用上下文 ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); //創建Application mInitialApplication = context.mPackageInfo.makeApplication(true, null); //調用Application的onCreate() mInitialApplication.onCreate(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate Application():" + e.toString(), e); } } // add dropbox logging to libcore DropBox.setReporter(new DropBoxReporter()); ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { @Override public void onConfigurationChanged(Configuration newConfig) { synchronized (mResourcesManager) { // We need to apply this change to the resources // immediately, because upon returning the view // hierarchy will be informed about it. if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { // This actually changed the resources! Tell // everyone about it. if (mPendingConfiguration == null || mPendingConfiguration.isOtherSeqNewer(newConfig)) { mPendingConfiguration = newConfig; sendMessage(H.CONFIGURATION_CHANGED, newConfig); } } } } @Override public void onLowMemory() { } @Override public void onTrimMemory(int level) { } }); }attach做的主要事情有:
/*** ContextImpl.java ***/ static ContextImpl createSystemContext(ActivityThread mainThread) { LoadedApk packageInfo = new LoadedApk(mainThread); ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY); context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), context.mResourcesManager.getDisplayMetricsLocked()); return context; } static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) { if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); return new ContextImpl(null, mainThread, packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY); }new ContextImpl時,系統上下文和應用上下文的參數是一樣的,createAppContext()的參數packageInfo,就是createSystemContext()中new的LoadedApk。
/*** ActivityThread.java ***/ private ContextImpl mSystemContext;
/*** LoadedApk.java ***/ public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { if (mApplication != null) { return mApplication; } Application app = null; String appClass = mApplicationInfo.className; //參數forceDefaultAppClass為true if (forceDefaultAppClass || (appClass == null)) { appClass = "android.app.Application"; } try { java.lang.ClassLoader cl = getClassLoader(); //此LoadedApk對象是createSystemContext時new的,mPackageName="android" if (!mPackageName.equals("android")) { initializeJavaContextClassLoader(); } //又創建了一個局部應用上下文 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); //創建Application app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); } catch (Exception e) { ... } //將前面創建的app添加到應用列表。 mActivityThread.mAllApplications.add(app); mApplication = app; ... return app; }
/*** SystemServer.java ***/ mSystemServiceManager = new SystemServiceManager(mSystemContext); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);這一步比較簡單,只是new了一個SystemServiceManager,並將其添加到本地服務列表中。
/*** SystemServiceManager.java ***/ //系統服務列表,系統服務必須繼承SystemService private final ArrayListmServices = new ArrayList (); //當前處於開機過程的哪個階段,SystemService.PHASE_XXXXX private int mCurrentPhase = -1; //通過類名啟動系統服務,可能會找不到類而拋異常 public SystemService startService(String className) { final Class serviceClass; try { serviceClass = (Class )Class.forName(className); } catch (ClassNotFoundException ex) { Slog.i(TAG, "Starting " + className); throw new RuntimeException("Failed to create service " + className + ": service class not found, usually indicates that the caller should " + "have called PackageManager.hasSystemFeature() to check whether the " + "feature is available on this device before trying to start the " + "services that implement it", ex); } return startService(serviceClass); } //創建並啟動系統服務,系統服務類必須繼承SystemService public T startService(Class serviceClass) { final String name = serviceClass.getName(); Slog.i(TAG, "Starting " + name); // Create the service. if (!SystemService.class.isAssignableFrom(serviceClass)) { throw new RuntimeException("Failed to create " + name + ": service must extend " + SystemService.class.getName()); } final T service; try { Constructor constructor = serviceClass.getConstructor(Context.class); service = constructor.newInstance(mContext); } catch (InstantiationException ex) { throw new RuntimeException("Failed to create service " + name + ": service could not be instantiated", ex); } catch (IllegalAccessException ex) { throw new RuntimeException("Failed to create service " + name + ": service must have a public constructor with a Context argument", ex); } catch (NoSuchMethodException ex) { throw new RuntimeException("Failed to create service " + name + ": service must have a public constructor with a Context argument", ex); } catch (InvocationTargetException ex) { throw new RuntimeException("Failed to create service " + name + ": service constructor threw an exception", ex); } // Register it. mServices.add(service); // Start it. try { service.onStart(); } catch (RuntimeException ex) { throw new RuntimeException("Failed to start service " + name + ": onStart threw an exception", ex); } return service; } //通知系統服務到了開機的哪個階段,會遍歷調用所有系統服務的onBootPhase()函數 public void startBootPhase(final int phase) { if (phase <= mCurrentPhase) { throw new IllegalArgumentException("Next phase must be larger than previous"); } mCurrentPhase = phase; Slog.i(TAG, "Starting phase " + mCurrentPhase); final int serviceLen = mServices.size(); for (int i = 0; i < serviceLen; i++) { final SystemService service = mServices.get(i); try { service.onBootPhase(mCurrentPhase); } catch (Exception ex) { throw new RuntimeException("Failed to boot service " + service.getClass().getName() + ": onBootPhase threw an exception during phase " + mCurrentPhase, ex); } } }
/*** SystemService.java ***/ /* * Boot Phases */ public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency? /** * After receiving this boot phase, services can obtain lock settings data. */ public static final int PHASE_LOCK_SETTINGS_READY = 480; /** * After receiving this boot phase, services can safely call into core system services * such as the PowerManager or PackageManager. */ public static final int PHASE_SYSTEM_SERVICES_READY = 500; /** * After receiving this boot phase, services can broadcast Intents. */ public static final int PHASE_ACTIVITY_MANAGER_READY = 550; /** * After receiving this boot phase, services can start/bind to third party apps. * Apps will be able to make Binder calls into services at this point. */ public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600; /** * After receiving this boot phase, services can allow user interaction with the device. * This phase occurs when boot has completed and the home application has started. * System services may prefer to listen to this phase rather than registering a * broadcast receiver for ACTION_BOOT_COMPLETED to reduce overall latency. */ public static final int PHASE_BOOT_COMPLETED = 1000; //子類必須定義只有一個Context參數的構造,並調用父類的此構造將Context參數傳給父類。 //SystemServiceManager創建SystemService時,使用反射機制調用的此構造方法 public SystemService(Context context) { mContext = context; } //啟動系統服務時,調用 public abstract void onStart(); //開機的每個階段都會調用 public void onBootPhase(int phase) {}
/*** SystemServer.java ***/ startBootstrapServices(); //啟動引導服務 startCoreServices(); //啟動核心服務 startOtherServices(); //啟動其他服務
/*** SystemServer.java ***/ private void startBootstrapServices() { //啟動Installer服務,阻塞等待與installd建立socket通道 Installer installer = mSystemServiceManager.startService(Installer.class); //啟動AMS(後面做詳細分析) mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); //啟動PowerManagerService mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); //PowerManagerService就緒,AMS初始化電源管理 mActivityManagerService.initPowerManagement(); //啟動LightsService mSystemServiceManager.startService(LightsService.class); //啟動DisplayManagerService(before package manager) mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); //初始化package manager之前,需要默認顯示。阻塞,10s超時,see DisplayManagerService.onBootPhase() mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); //當設備正在加密時,僅運行核心應用 String cryptState = SystemProperties.get("vold.decrypt"); if (ENCRYPTING_STATE.equals(cryptState)) { Slog.w(TAG, "Detected encryption in progress - only parsing core apps"); mOnlyCore = true; } else if (ENCRYPTED_STATE.equals(cryptState)) { Slog.w(TAG, "Device encrypted - only parsing core apps"); mOnlyCore = true; } //啟動PackageManagerService Slog.i(TAG, "Package Manager"); mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); //將UserManagerService添加到服務列表,該服務是在PackageManagerService中初始化的 Slog.i(TAG, "User Service"); ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance()); //初始化用來緩存包資源的屬性緩存 AttributeCache.init(mSystemContext); //設置AMS mActivityManagerService.setSystemProcess(); //啟動傳感器服務(native 服務,依賴PackageManagerService、AppOpsService、permissions service) startSensorService(); }這步首先等待installd啟動完成,然後啟動一些相互依賴的關鍵服務。
/*** SystemServer.java ***/ /** * Starts some essential services that are not tangled up in the bootstrap process. */ private void startCoreServices() { //啟動BatteryService,用於統計電池電量,需要LightService mSystemServiceManager.startService(BatteryService.class); //啟動UsageStatsService,用於統計應用使用情況 mSystemServiceManager.startService(UsageStatsService.class); mActivityManagerService.setUsageStatsManager( LocalServices.getService(UsageStatsManagerInternal.class)); // Update after UsageStatsService is available, needed before performBootDexOpt. mPackageManagerService.getUsageStatsIfNoPackageUsageInfo(); //啟動WebViewUpdateService mSystemServiceManager.startService(WebViewUpdateService.class); }啟動服務BatteryService,UsageStatsService,WebViewUpdateService。
此函數代碼較長,但是邏輯簡單,主要是啟動各種服務。以下代碼僅按順序列出啟動的服務,有些服務根據條件,如是否是工廠模式,或系統屬性配置,選擇性啟動,這裡不考慮條件判斷和異常處理。
/*** SystemServer.java ***/ private void startOtherServices() { ... try { SchedulingPolicyService // 調度策略 TelecomLoaderService // TelephonyRegistry // 提供電話注冊、管理服務,可以獲取電話的鏈接狀態、信號強度等 EntropyMixer // 隨機數相關,原名EntropyService。 參考“EntropyService分析” CameraService // AccountManagerService // 提供所有賬號、密碼、認證管理等等的服務 ContentService // ContentProvider服務,提供跨進程數據交換 VibratorService // 振動器服務 ConsumerIrService // 紅外遠程控制服務 AlarmManagerService // 提供鬧鈴和定時器等功能 //初始化 Watchdog。是在AMS的systemReady回調中運行的:Watchdog.getInstance().start(); final Watchdog watchdog = Watchdog.getInstance(); watchdog.init(context, mActivityManagerService); WindowManagerService // 窗口管理服務 InputManagerService // 事件傳遞分發服務 BluetoothService // 藍牙服務 } catch (RuntimeException e) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting core service", e); } InputMethodManagerService // 輸入法服務 AccessibilityManagerService // 輔助管理程序截獲所有的用戶輸入,並根據這些輸入給用戶一些額外的反饋,起到輔助的效果 MountService // 掛載服務 UiModeManagerService // 管理當前Android設備的夜間模式和行車模式 //frameworks/base/core/res/res/values-zh-rCN/strings.xml ActivityManagerNative.getDefault().showBootMessage( context.getResources().getText( com.android.internal.R.string.android_upgrading_starting_apps), false); LockSettingsService // 屏幕鎖定服務,管理每個用戶的相關鎖屏信息 PersistentDataBlockService // DeviceIdleController // Doze模式的主要驅動,參考“深入Android 'M' Doze” DevicePolicyManagerService // 提供一些系統級別的設置及屬性 StatusBarManagerService // 狀態欄管理服務 ClipboardService // 系統剪切板服務 NetworkManagementService // 網絡管理服務 TextServicesManagerService // 文本服務,例如文本檢查等 NetworkScoreService // 網絡評分服務 NetworkStatsService // 網絡狀態服務 NetworkPolicyManagerService // 網絡策略服務 WifiP2pService // Wifi Direct服務 WifiService // Wifi服務 WifiScanningService // Wifi掃描服務 RttService // Wifi相關 EthernetService // 以太網服務 ConnectivityService // 網絡連接管理服務 NsdService // 網絡發現服務(Network Service Discovery Service) UpdateLockService // //等待MountService完全啟動,後面有些依賴 mountService.waitForAsecScan(); accountManager.systemReady(); contentService.systemReady(); NotificationManagerService // 通知欄管理服務 DeviceStorageMonitorService // 磁盤空間狀態檢測服務 LocationManagerService // 位置服務,GPS、定位等 CountryDetectorService // 檢測用戶國家 SearchManagerService // 搜索管理服務 DropBoxManagerService // 用於系統運行時日志的存儲於管理 WallpaperManagerService // 壁紙管理服務 AudioService // AudioFlinger的上層管理封裝,主要是音量、音效、聲道及鈴聲等的管理 DockObserver // 如果系統有個座子,當手機裝上或拔出這個座子的話,就得靠他來管理了 WiredAccessoryManager // 監視手機和底座上的耳機 MidiService // UsbService // USB服務 SerialService // 串口服務 TwilightService // 指出用戶當前所在位置是否為晚上,被UiModeManager等用來調整夜間模式。 JobSchedulerService // BackupManagerService // 備份服務 AppWidgetService // 提供Widget的管理和相關服務 VoiceInteractionManagerService // 語音交互管理服務 DiskStatsService // 磁盤統計服務,供dumpsys使用 SamplingProfilerService // 用於耗時統計等 NetworkTimeUpdateService // 監視網絡時間,當網絡時間變化時更新本地時間。 CommonTimeManagementService // 管理本地常見的時間服務的配置,在網絡配置變化時重新配置本地服務。 CertBlacklister // 提供一種機制更新SSL certificate blacklist DreamManagerService // 屏幕保護 AssetAtlasService // 負責將預加載的bitmap組裝成紋理貼圖,生成的紋理貼圖可以被用來跨進程使用,以減少內存。 GraphicsStatsService // PrintManagerService // 打印服務 RestrictionsManagerService // MediaSessionService // HdmiControlService // HDMI控制服務 TvInputManagerService // MediaRouterService // TrustManagerService // FingerprintService // 指紋服務 BackgroundDexOptService // 主要用於classes文件的odex優化 LauncherAppsService // MediaProjectionManagerService // 管理媒體投影會話 MmsServiceBroker // MmsService的代理 // It is now time to start up the app processes... vibrator.systemReady(); lockSettings.systemReady(); // Needed by DevicePolicyManager for initialization mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY); mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); wm.systemReady(); if (safeMode) { mActivityManagerService.showSafeModeOverlay(); } // Update the configuration for this context by hand context.getResources().updateConfiguration(config, metrics); mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService()); mPackageManagerService.systemReady(); mDisplayManagerService.systemReady(safeMode, mOnlyCore); mActivityManagerService.systemReady(new Runnable() { @Override public void run() { mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY); mActivityManagerService.startObservingNativeCrashes(); WebViewFactory.prepareWebViewInSystemServer(); startSystemUi(context); networkScoreF.systemReady(); networkManagementF.systemReady(); networkStatsF.systemReady(); networkPolicyF.systemReady(); connectivityF.systemReady(); audioServiceF.systemReady(); //開啟 Watchdog Watchdog.getInstance().start(); mSystemServiceManager.startBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); wallpaperF.systemRunning(); immF.systemRunning(statusBarF); locationF.systemRunning(); countryDetectorF.systemRunning(); networkTimeUpdaterF.systemRunning(); commonTimeMgmtServiceF.systemRunning(); textServiceManagerServiceF.systemRunning(); atlasF.systemRunning(); inputManagerF.systemRunning(); telephonyRegistryF.systemRunning(); mediaRouterF.systemRunning(); mmsServiceF.systemRunning(); } }); }
ToDoList(fragment) 詳解 版權所有, 禁止轉載, 如有需要, 請站內聯系. Fragment(碎片) 可以靈活
前言很長一段時間沒寫博客了,再不寫點東西真說不過去,把工作上的一些有價值的東西整理出來分享,在當下還有點時效性,不然遲早會爛在肚子裡的。還記得之前小巫有個開源計劃是想實現
開發中很常見的一個問題,項目中的listview不僅僅是簡單的文字,常常需要自己定義listview,自己的Adapter去繼承BaseAdapter,在adapter
ActionBar動作欄 一、ActionBar:(動作欄) (一)、簡介:(擴展TitleBar) Action bar(動作欄)是一個導航控