標籤:
以下分析是基於MTK Android4.4原生的SystemUI與Google 的SystemUI有微小的區別,但兩者的整體架構是差不多的。
這一篇是分析SystemUI的第一篇,先從最簡單的PowerUI著手,源碼路徑:/frameworks/base/packages/SystemUI 程式目錄結構如下:
我匯入Eclipse編輯,報錯的原因是因為找不到Framework上的一些包和資源,這個沒有關係;修改完後在使用mmm模組編譯,再push到手機(eng版本)上進行調試,push後需要重啟才會生效。
在AndroidManifest.xml上沒有Activity註冊
<intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter>
所以整個程式啟動是從外部啟動SystemUIService的。那麼是如何啟動SystemUIService的呢?看下這個檔案:/frameworks/base/services/java/com/android/server/SystemServer.java在這個檔案中可以找到
static final void startSystemUi(Context context) { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.android.systemui", "com.android.systemui.SystemUIService")); //Slog.d(TAG, "Starting service: " + intent); context.startServiceAsUser(intent, UserHandle.OWNER); }所以SystemUI在SystemService啟動時就被調用了。
SystemUIService的關鍵代碼如下:
package com.android.systemui;import android.app.Service;import android.content.Intent;import android.content.res.Configuration;import android.os.IBinder;import android.util.Log;import java.io.FileDescriptor;import java.io.PrintWriter;import java.util.HashMap;public class SystemUIService extends Service { private static final String TAG = "SystemUIService"; /** * The classes of the stuff to start. */ private final Class<?>[] SERVICES = new Class[] { com.android.systemui.recent.Recents.class, com.android.systemui.statusbar.SystemBars.class, com.android.systemui.usb.StorageNotification.class, com.android.systemui.power.PowerUI.class, com.android.systemui.media.RingtonePlayer.class, com.android.systemui.settings.SettingsUI.class, }; /** * Hold a reference on the stuff we start. */ private final SystemUI[] mServices = new SystemUI[SERVICES.length]; @Override public void onCreate() { HashMap<Class<?>, Object> components = new HashMap<Class<?>, Object>(); final int N = SERVICES.length; for (int i=0; i<N; i++) { Class<?> cl = SERVICES[i]; Log.d(TAG, "loading: " + cl); Log.d("dzt", "loading: " + cl); try { mServices[i] = (SystemUI)cl.newInstance(); } catch (IllegalAccessException ex) { throw new RuntimeException(ex); } catch (InstantiationException ex) { throw new RuntimeException(ex); } mServices[i].mContext = this; mServices[i].mComponents = components; Log.d(TAG, "running: " + mServices[i]); Log.d("dzt", "running: " + mServices[i]); mServices[i].start(); } }}這些類
com.android.systemui.recent.Recents.class, com.android.systemui.statusbar.SystemBars.class, com.android.systemui.usb.StorageNotification.class, com.android.systemui.power.PowerUI.class, com.android.systemui.media.RingtonePlayer.class, com.android.systemui.settings.SettingsUI.class,
都是繼承於:SystemUI,在SystemUIService的OnCreate()函數中會建立執行個體,並調用mServices[i].start();方法。
下面就分析最簡單的com.android.systemui.power.PowerUI.class
在PowerUI的start()方法中,註冊一些監聽器
public void start() { mLowBatteryAlertCloseLevel = mContext.getResources().getInteger( com.android.internal.R.integer.config_lowBatteryCloseWarningLevel); mLowBatteryReminderLevels[0] = mContext.getResources().getInteger( com.android.internal.R.integer.config_lowBatteryWarningLevel); mLowBatteryReminderLevels[1] = mContext.getResources().getInteger( com.android.internal.R.integer.config_criticalBatteryWarningLevel); final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mScreenOffTime = pm.isScreenOn() ? -1 : SystemClock.elapsedRealtime(); // Register for Intent broadcasts for... IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_SCREEN_ON); /// M: Support show battery level when configuration changed. @{ filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); /// M: Support show battery level when configuration changed. @} /// M: Hide low battery dialog when PowerOffAlarm ring. @{ filter.addAction("android.intent.action.normal.boot"); filter.addAction("android.intent.action.ACTION_SHUTDOWN_IPO"); /// M: Hide low battery dialog when PowerOffAlarm ring. @} mContext.registerReceiver(mIntentReceiver, filter, null, mHandler); }例如監聽ACTION_BATTERY_CHANGED判斷電量的大小,如果低電給一個提示給使用者,其它的ACTION也都是根據廣播來處理一些特定的事情,如果跟電源相關功能需要定製或添加新的監聽器都可以在這個類中修改。
Android4.4 SystemUI分析之PowerUI