Android的网络信号栏的显示刷新也是SystemUI的一部分,主要业务逻辑也是在SystemUI这模块内的,整个流程的开始是在PhoneStatusBar.java内的,
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java;
先从布局方面入手:
由PhoneStatusBar.java的makeStatusBarView()统一加载super_status_bar.xml的。而在Android中,SystemUI上显示信号状态栏的地方主要由三处,分别是状态栏、锁屏界面下的状态栏以及下拉通知栏的快捷设置区域。这三个引用处分别是status_bar.xml、keyguard_status_bar.xml、status_bar_expanded_header.xml;而这三个布局文件都会去include一个system_icons.xml布局,
这个布局就是所要寻找的网络信号栏显示和电池图标显示view的地方。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/system_icons"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical">
<com.android.keyguard.AlphaOptimizedLinearLayout android:id="@+id/statusIcons"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal"/>
<include layout="@layout/signal_cluster_view"
android:id="@+id/signal_cluster"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2.5dp"/>
<!-- battery must be padded below to match assets -->
<com.android.systemui.BatteryMeterView android:id="@+id/battery"
android:layout_height="14.5dp"
android:layout_width="9.5dp"
android:layout_marginBottom="@dimen/battery_margin_bottom"/>
</LinearLayout>
这个布局又会去include一个signal_cluster_view.xml布局,即这个布局才是具体的信号栏的布局文件
<com.android.systemui.statusbar.SignalClusterView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingEnd="@dimen/signal_cluster_battery_padding"
>
<ImageView
android:id="@+id/vpn"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingEnd="6dp"
android:src="@drawable/stat_sys_vpn_ic"
/>
<FrameLayout
android:id="@+id/wifi_combo"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
>
<ImageView
android:id="@+id/wifi_signal"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
</FrameLayout>
<View
android:id="@+id/wifi_signal_spacer"
android:layout_width="4dp"
android:layout_height="4dp"
android:visibility="gone"
/>
<LinearLayout
android:id="@+id/mobile_signal_group"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
>
</LinearLayout>
<ImageView
android:id="@+id/no_sims"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/stat_sys_no_sims"
/>
<View
android:id="@+id/wifi_airplane_spacer"
android:layout_width="4dp"
android:layout_height="4dp"
android:visibility="gone"
/>
<ImageView
android:id="@+id/airplane"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
</com.android.systemui.statusbar.SignalClusterView>
代码逻辑方面:
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
makeStatusBarView()方法:
在这个方法内先去创建两个控制器mNetworkController、mSecurityController;
mNetworkController = new NetworkControllerImpl(mContext, mHandlerThread.getLooper());
mSecurityController = new SecurityControllerImpl(mContext);
NetworkControllerImpl.java继承于BroadcastReceiver,再看下NetworkControllerImpl的构造方法:
public NetworkControllerImpl(Context context, Looper bgLooper) {
this(context, (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE),
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE),
(WifiManager) context.getSystemService(Context.WIFI_SERVICE),
SubscriptionManager.from(context), Config.readConfig(context), bgLooper,
new CallbackHandler(),
new AccessPointControllerImpl(context, bgLooper),
new MobileDataControllerImpl(context),
new SubscriptionDefaults());
mReceiverHandler.post(mRegisterListeners);
}
这个构造方法内部会先去调用一个另外的构造方法;
@VisibleForTesting
NetworkControllerImpl(Context context, ConnectivityManager connectivityManager,
TelephonyManager telephonyManager, WifiManager wifiManager,
SubscriptionManager subManager, Config config, Looper bgLooper,
CallbackHandler callbackHandler,
AccessPointControllerImpl accessPointController,
MobileDataControllerImpl mobileDataController,
SubscriptionDefaults defaultsHandler) {
mContext = context;
mConfig = config;
mReceiverHandler = new Handler(bgLooper);
mCallbackHandler = callbackHandler;
mSubscriptionManager = subManager;
mSubDefaults = defaultsHandler;
mConnectivityManager = connectivityManager;
mHasMobileDataFeature =
mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
// telephony
mPhone = telephonyManager;
// wifi
mWifiManager = wifiManager;