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

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

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

这里写图片描述

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

(请原谅我拙劣的画工)
这里写图片描述

这里主要以最后查询到的 用于放置信号图标的直接父容器,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()方法,看来是回调了。<未完待续>