SystemUI源码分析

本文深入探讨了Android 5.1 SystemUI的源码,从AndroidManifest.xml开始,详细分析了SystemUIApplication的启动过程,再到SystemUIService如何通过startService()和bindService()启动。接着,文章揭示了SystemBars.java中的关键组件和服务,尤其是status bar的创建和布局,包括StatusBarWindowView的加载。最后,文中以brightness_slider为例,展示了快速设置亮度滑块的实现路径,以及header视图位置信息的更新机制。通过对SystemUI的源码分析,文章为理解Android系统的运行机制提供了宝贵见解。
摘要由CSDN通过智能技术生成

此篇文章针对android5.1 systemUI源码进行分析

下面我们进行分析,
1.1 frameworks/base/packages/SystemUI/AndroidManifest.xml
我们先来看下这个文件下的内容:
android:name=”.SystemUIApplication”
android:persistent=”true”
android:allowClearUserData=”false”
android:allowBackup=”false”
android:hardwareAccelerated=”true”
android:label=”@string/app_label”
android:icon=”@drawable/icon”
android:process=”com.android.systemui”
android:supportsRtl=”true”
android:theme=”@style/systemui_theme”>
………………………………………
android:exported=”true”
/>
android:process=”:screenshot”
android:exported=”false” />
android:exported=”true” />
android:permission=”android.permission.BIND_WALLPAPER”
android:exported=”true” />
………………………………………
………………………………………
………………………………………

 我们可以看到,AndroidManifest.xml注册了很多的service 和 广播,那么是怎么启动的服务呢?
    我们继续看下这个所注册的三个服务,
               SystemUIService /
               .screenshot.TakeScreenshotService /
              .LoadAverageService/.ImageWallpaper

这三个服务是怎么启动的呢,我们仔细来看下这句注释:
“Broadcast receiver that gets the broadcast at boot time and starts up everything else.”
看里这个注释,我们就应该知道,首先启动的应该是SystemUIService这个服务。
那么SystemUIService这个服务是怎么启动的呢,启动服务我们知道多数的通用方法是
startService(intent)和bindService(intent)
那么我们就在SystemUI下全局搜索“SystemUIService”,可以看下结果
frameworks/base/services/java/com/android/server/SystemServer.java: “com.android.systemui.SystemUIService”));
我们打开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);
}

原来是 intent.setComponent()启动了SystemUIService这个服务。

1.2 frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java

下面我们来分析一下SystemUIService.java:

@Override
    public void onCreate() {
        super.onCreate();
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();
    }

在oSystemUIService中的onCreate只调用了
((SystemUIApplication) getApplication()).startServicesIfNeeded();
这么一个语句,下面我们来看看startServicesIfNeeded()这里面有啥东西

public void startServicesIfNeeded() {        
    if (mServicesStarted) {         
        return;
    }                               
    if (!mBootCompleted) {          
        // check to see if maybe it was already completed long before we began
        // see ActivityManagerService.finishBooting()
        if ("1".equals(SystemProperties.get("sys.boot_completed"))) { 
            mBootCompleted = true;  
            if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent");        
        }
    }

    Log.v(TAG, "Starting SystemUI services.");
    final int N = SERVICES.length;  
    for (int i=0; i<N; i++) {       
        Class<?> cl = SERVICES[i];  
        if (DEBUG) Log.d(TAG, "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 = mComponents;  
        if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
        mServices[i].start();

        if (mBootCompleted) {
            mServices[i].onBootCompleted();      
        }
    }
    mServicesStarted = true;
}

}

在这里我们看到mServices启动了不止一个服务,那么这些都是那些服务呢,
我们看这个语句
mServices[i] = (SystemUI)cl.newInstance();
这里的语句付给了mServices[i].start()一个对象,
我们往上去找,可以看到这Class cl = SERVICES[i];
cl是SERVICES[i]这个数组中的一个值,在java的定义中,我们可以看到这个SERVICES的初始化
private final Class[] SERVICES = new Class[] {
com.android.systemui.keyguard.KeyguardViewMediator.class,
com.android.systemui.recent.Recents.class,
com.android.systemui.volume.VolumeUI.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
};
SERVICES中添加要start的所有服务选项,这里,我们重点关注一下
com.android.systemui.statusbar.SystemBars.class,
这是我们进行下一步分析的重要线索。

1.3 frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java

我们看下SystemBars.java这个文件中的start()中到底写了些什么东西,

public void start() {
    if (DEBUG) Log.d(TAG, "start");
    mServiceMonitor = new ServiceMonitor(TAG, DEBUG,
            mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);
    mServiceMonitor.start();  // will call onNoService if no remote service is found
}   

这里,启动了另外一个服务mServiceMonitor,除了启动这个服务外什么都没有做,那我们继续往下面去看看
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/ServiceMonitor.java
在这个文件里面,对star()方法的调用
public void start() {
…………………
mHandler.sendEmptyMessage(MSG_START_SERVICE);
}
在这个函数里,这个sendEmptyMessage语句是一个非常关键的调用,这个调用也是启动了一个服务,我们去看下这个mHandler都干了些啥事,

private final Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch(msg.what) {
case MSG_START_SERVICE:
startService();
break;
case MSG_CONTINUE_START_SERVICE:
continueStartService();
break;
case MSG_STOP_SERVICE:
stopService();
break;
case MSG_PACKAGE_INTENT:
packageIntent((Intent)msg.obj);
break;
case MSG_CHECK_BOUND:
checkBound();
break;
case MSG_SERVICE_DISCONNECTED:
serviceDisconnected((ComponentName)msg.obj);
break;
}
}
};

在这里我们看到
case MSG_START_SERVICE:
startService();
break;
这里才是真正的启动了一个服务,mCallbacks.onNoService();
private void startService() {
mServiceName = getComponentNameFromSetting();
if (mDebug) Log.d(mTag, “startService mServiceName=” + mServiceName);
if (mServiceName == null) {
mBound = false;
mCallbacks.onNoService();
} else {
long delay = mCallbacks.onServiceStartAttempt();
mHandler.sendEmptyMessageDelayed(MSG_CONTINUE_START_SERVICE, delay);
}
}
我们来看下if (mServiceName == null) 这个判断的结果是怎么来的,
private ComponentName getComponentNameFromSetting() {
String cn = Settings.Secure.getStringForUser(mContext.getContentResolver(),
mSettingKey, UserHandle.USER_CURRENT);
return cn == null ? null : ComponentName.unflattenFromString(cn);
}
由以上的代码我们可知,cn返回的是null值,在startService()中就调用了 mCallbacks.onNoService();

我们来看下frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java
onNoService()的调用,

public void onNoService() {
if (DEBUG) Log.d(TAG, “onNoService”);
createStatusBarFromConfig();
}

private void createStatusBarFromConfig() {
…………………………………..
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
mStatusBar.start();
…………………………………..
}
在createStatusBarFromConfig()中终于有了实际的行动来进行关于status的一下相关操作了,一直到这里,其实前面所做的都是一些服务的调用,并没有对screen进行任何的view类级别的操作,其实上面的流程,只是在系统框架先进行的一些服务注册,及逻辑方面的一些准备。

1.4 frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
下面我们来着重分析下BaseStatusBar.start().

public void start() {
…………………….
createAndAddWindows();
…………………….
}
在BaseStatusBar.start()中,这个语句是重点中的重点,是对整个status的布局,我们进到这个函数中去看个究竟
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
public void createAndAddWindows() {
addStatusBarWindow();
}
在createAndAddWindows中也只是调用了这么一个函数,没有其他的东西了,我们接着看
addStatusBarWindow();
其实在addStatusBarWindow所做的东西也不多,就是两步
makeStatusBarView()和mStatusBarWindowManager.add();
但是这两步确实非常重要的两部。
private void addStatusBarWindow() {
makeStatusBarView();
mStatusBarWindowManager = new StatusBarWindowManager(mContext);
mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
}

我们先来看看akeStatusBarView()这个里面是什么情况
protected PhoneStatusBarView makeStatusBarView() {
…………………………
mStatusBarWindow = (StatusBarWindowView) View.inflate(context,R.layout.super_status_bar, null);
…………………………..

}

我们在super_status_bar.xml中这个文件可以看到
<-com.android.systemui.statusbar.phone.StatusBarWindowView
//xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:fitsSystemWindows=”true”>
…………………………..
<-com.android.systemui.statusbar.ScrimView android:id=”@+id/scrim_behind” <

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值