天天看点

安卓7.0 状态栏分析 01----> 信号栏更新

之前写的文章都是关于软件设置方面的,用来为安装软件和系统来做一些记录,让其他人少绕弯道,今天正式开始更新技术博客。
先简后难吧,我选择了安卓7.0的systemUI中的状态栏开始入手,由于systenUI中的代码涉及的还是比较广的,这里就拆分开来写,以后慢慢持续更新!
一般的分析systenUI都会从它的启动来分析,但是类似于这样的文章网上有很多,我就不再赘述了,这里提供网址,想要了解启动流程的可以自行去看
http://blog.csdn.net/qq_31530015/article/details/53507968

这篇文章不仅介绍了启动流程,还对布局进行了讲解,是从大局观上来讲的。可以了解整个systemUI的视图流程。
           

闲话少叙,开始具体分析更新流程,这里我还是从视图入手。

安卓7.0 状态栏分析 01----> 信号栏更新

个人 习惯,喜欢从布局入手。这里我用了sdk中的 hierarchy 找到了这个视图的布局。这里大致介绍一下systemUI整个布局的联系。

(请原谅我拙劣的画工)

安卓7.0 状态栏分析 01----> 信号栏更新

这里主要以最后查询到的 用于放置信号图标的直接父容器,LinearLayout的id着手,在systemUI全局中找寻到下面:

在类SignalClusterView中有如下代码:

mMobileSignalGroup = (LinearLayout) findViewById(R.id.mobile_signal_group);

然后追寻mMobileSignalGroup 找到了

mMobileSignalGroup.addView(state.mMobileGroup);

@Override

protected void onAttachedToWindow() {

super.onAttachedToWindow();

for (PhoneState state : mPhoneStates) {
        mMobileSignalGroup.addView(state.mMobileGroup);
    }

    int endPadding = mMobileSignalGroup.getChildCount() > 0 ? mMobileSignalGroupEndPadding : 0;
    mMobileSignalGroup.setPaddingRelative(0, 0, endPadding, 0);

    TunerService.get(mContext).addTunable(this, StatusBarIconController.ICON_BLACKLIST);

    apply();
    applyIconTint();
    mNC.addSignalCallback(this);
}
           

这里需要注意mPhoneStates是一个集合,这个集合里面有几个对象就代表目前手机插着几张sim卡。

然后再跳到phonestate:

public PhoneState(int subId, Context context) {

ViewGroup root = (ViewGroup) LayoutInflater.from(context)

.inflate(R.layout.mobile_signal_group, null);

setViews(root);

mSubId = subId;

}

接着 setViews(root);

public void setViews(ViewGroup root) {

mMobileGroup = root;

…………………………

}

可以看到真正的布局其实就是mobile_signal_group.xml

这里将这个布局文件代码贴出来

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:systemui="http://schemas.android.com/apk/res-auto"
    android:id="@+id/mobile_combo"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    >
    <ImageView
        android:id="@+id/embms"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="2dp"
        android:layout_marginEnd="4dp"
        android:visibility="gone"
        />
    <ImageView
        android:id="@+id/dataNetwork_type"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginEnd="2dp"
        android:visibility="gone"
        />
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="2dp"
        android:id="@+id/data_inout"
        android:visibility="gone"
        />
    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        >
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
        >
        <ImageView
            android:id="@+id/mobile_roaming"
            android:layout_width="wrap_content"
            android:layout_height="17dp"
            android:paddingStart="22dp"
            android:paddingTop="1.5dp"
            android:paddingBottom="3dp"
            android:scaleType="fitCenter"
            android:src="@drawable/stat_sys_roaming"
            android:contentDescription="@string/accessibility_data_connection_roaming"
            android:visibility="gone"
            />
        <FrameLayout
            android:id="@+id/mobile_signal_single"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            >
            <com.android.systemui.statusbar.AnimatedImageView
                android:theme="@style/DualToneLightTheme"
                android:id="@+id/mobile_signal"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                systemui:hasOverlappingRendering="false"
                />
            <com.android.systemui.statusbar.AnimatedImageView
                android:theme="@style/DualToneDarkTheme"
                android:id="@+id/mobile_signal_dark"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:alpha="0.0"
                systemui:hasOverlappingRendering="false"
                />
            <ImageView
                android:id="@+id/mobile_type"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                />
            <ImageView
                android:id="@+id/mobile_inout"
                android:layout_height="17dp"
                android:layout_width="17dp"
                android:layout_gravity="end|center_vertical"
                android:layout_marginBottom="0.8dp"
                android:layout_marginRight="1.5dp"
                />
        </FrameLayout>
        <LinearLayout
            android:id="@+id/mobile_signal_stacked"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:visibility="gone"
            >
            <ImageView
                android:id="@+id/mobile_signal_data"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                />
            <ImageView
                android:id="@+id/mobile_signal_voice"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                />
        </LinearLayout>
        </LinearLayout>
    </FrameLayout>
</LinearLayout>
           

这里分的很细致,但是分析方法大致都一样,我们主要来分析状态栏的信号强度(表现在信号的格数)和信号type(4g,3g等)。

<com.android.systemui.statusbar.AnimatedImageView
                android:theme="@style/DualToneLightTheme"
                android:id="@+id/mobile_signal"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                systemui:hasOverlappingRendering="false"
                />
           

遵循这个布局找到id为mobile_signal的AnimatedImageView。

最终发现他的动态改变是在phoneState中的apply()中发生的

public boolean apply(boolean isSecondaryIcon) {
            if (mMobileVisible && !mIsAirplaneMode) {
                if (mLastMobileStrengthId != mMobileStrengthId) {
                    updateAnimatableIcon(mMobile, mMobileStrengthId);
                    updateAnimatableIcon(mMobileDark, mMobileStrengthId);
                    mLastMobileStrengthId = mMobileStrengthId;
                }

                if (mLastMobileTypeId != mMobileTypeId) {
                    mMobileType.setImageResource(mMobileTypeId);
                    mLastMobileTypeId = mMobileTypeId;
                }
。。。。。。。。。。。。。。。。。。。。。。。。。
}
           

以这个方法为分界点!

向上追(调用它的地方)可以找到信号改变的源码!

向下追(它调用的地方)可以找到,信号改变过程中需要的各种资源的位置。

我们首先向上追,发现SignalClusterView中的apply()调用了它,而SignalClusterView继承了SignalCallback,在实现该接口的所有方法中都调用到了自己的apply()方法,看来是回调了。<未完待续>