上一篇讲到,SystemUIApplication中,会加载各种服务并启动,Dependency就是其中之一并且是第一个被启动的服务:

源码中对Dependency的介绍:

Dependencies

The first SystemUI service that is started should always be Dependency.Dependency provides a static method for getting a hold of dependencies thathave a lifecycle that spans sysui. Dependency has code for how to create alldependencies manually added. SystemUIFactory is also capable ofadding/replacing these dependencies.Dependencies are lazily initialized, so if a Dependency is never referenced atruntime, it will never be created.If an instantiated dependency implements Dumpable it will be included in dumpsof sysui (and bug reports), allowing it to include current state information.This is how \*Controllers dump state to bug reports.If an instantiated dependency implements ConfigurationChangeReceiver it willreceive onConfigurationChange callbacks when the configuration changes.

大致就是说:(Google translate)
启动的第一个SystemUI服务应始终为Dependency。
Dependency提供了一种静态方法,用于获取具有跨越sysui的生命周期的依赖项。 Dependency具有如何创建手动添加的所有依赖项的代码。 SystemUIFactory还能够添加/替换这些依赖项。

依赖项是惰性初始化的,因此如果从未在运行时引用依赖项,则永远不会创建它。

如果实例化的依赖项实现Dumpable,它将包含在sysui(和bug报告)的转储中,允许它包含当前状态信息。 这就是\ *控制器将状态转储到错误报告的方式。

如果实例化的依赖项实现ConfigurationChangeReceiver,它将在配置更改时接收onConfigurationChange回调。

在Dependency的start方法中:初始化了注入NetworkController依赖的方式:

@Override    public void start() {        // TODO: Think about ways to push these creation rules out of Dependency to cut down        // on imports.        mProviders.put(TIME_TICK_HANDLER, () -> {            HandlerThread thread = new HandlerThread("TimeTick");            thread.start();            return new Handler(thread.getLooper());        });        ......        mProviders.put(NetworkController.class, () ->                new NetworkControllerImpl(mContext, getDependency(BG_LOOPER),                        getDependency(DeviceProvisionedController.class)));        ......

具体Dependency如何加载服务的这里先不说,只要知道NetworkController.class最终注入的是NetworkControllerImpl

再回到信号显示,这个事件发生自StatusBar中,直接上StatusBar的start方法:

@Override    public void start() {        mGroupManager = Dependency.get(NotificationGroupManager.class);        mVisualStabilityManager = Dependency.get(VisualStabilityManager.class);        mNotificationLogger = Dependency.get(NotificationLogger.class);        mRemoteInputManager = Dependency.get(NotificationRemoteInputManager.class);        mNotificationListener =  Dependency.get(NotificationListener.class);        mGroupManager = Dependency.get(NotificationGroupManager.class);        mNetworkController = Dependency.get(NetworkController.class);        mUserSwitcherController = Dependency.get(UserSwitcherController.class);        mScreenLifecycle = Dependency.get(ScreenLifecycle.class);        mScreenLifecycle.addObserver(mScreenObserver);        ......        if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {            mNetworkController.dispatchDemoCommand(command, args);        }}

在这里会获取NetworkController对象,Dependency就会注入NetworkControllerImpl,在NetNetworkControllerImpl构造方法中,会注册监听器,监听MobileSignal、WiFi等等状态信息变化:

    public NetworkControllerImpl(Context context, Looper bgLooper,            DeviceProvisionedController deviceProvisionedController) {        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),                new DataUsageController(context),                new SubscriptionDefaults(),                deviceProvisionedController);        mReceiverHandler.post(mRegisterListeners);    }//mRegisterListeners实现了Runnable接口,内部进行监听注册private final Runnable mRegisterListeners = new Runnable() {        @Override        public void run() {            registerListeners();        }    };//注册监听器private void registerListeners() {        for (int i = 0; i < mMobileSignalControllers.size(); i++) {            MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);            mobileSignalController.registerListener();        }        if (mSubscriptionListener == null) {            mSubscriptionListener = new SubListener();        }        mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);        mPhone.listen(mPhoneStateListener, LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);        // broadcasts        IntentFilter filter = new IntentFilter();        filter.addAction(WifiManager.RSSI_CHANGED_ACTION);        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);        filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);        filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);        filter.addAction(TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);        filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);        filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);        filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);        filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);        mContext.registerReceiver(this, filter, null, mReceiverHandler);        mListening = true;        updateMobileControllers();    }

信号变化的监听就是由MobileSignalController负责的,这个类主要是用来对信号强度、运营商、网络类型等以及根据这些状态封装对应Icon的控制器, 看一下MobileSignalController的registerListener()方法:

/**     * Start listening for phone state changes.     */    public void registerListener() {        mPhone.listen(mPhoneStateListener,                PhoneStateListener.LISTEN_SERVICE_STATE                        | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS                        | PhoneStateListener.LISTEN_CALL_STATE                        | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE                        | PhoneStateListener.LISTEN_DATA_ACTIVITY                        | PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE);        mContext.getContentResolver().registerContentObserver(Global.getUriFor(Global.MOBILE_DATA),                true, mObserver);        mContext.getContentResolver().registerContentObserver(Global.getUriFor(                Global.MOBILE_DATA + mSubscriptionInfo.getSubscriptionId()),                true, mObserver);    }

通过TelephonyManager注册监听,当telephony状态发生变化时,会调用updateTelephony()方法进行状态更新

private final void updateTelephony() {        ......        notifyListenersIfNecessary();    }public void notifyListenersIfNecessary() {        if (isDirty()) {            saveLastState();            notifyListeners();        }    }public final void notifyListeners() {        notifyListeners(mCallbackHandler);    }

notifyListeners是抽象类SignalListener的一个抽象方法,由MobileSignalController自己实现:

@Override    public void notifyListeners(SignalCallback callback) {        MobileIconGroup icons = getIcons();        ......        boolean activityIn = mCurrentState.dataConnected                && !mCurrentState.carrierNetworkChangeMode                && mCurrentState.activityIn;        boolean activityOut = mCurrentState.dataConnected                && !mCurrentState.carrierNetworkChangeMode                && mCurrentState.activityOut;        showDataIcon &= mCurrentState.isDefault || dataDisabled;        int typeIcon = (showDataIcon || mConfig.alwaysShowDataRatIcon) ? icons.mDataType : 0;        callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon,                activityIn, activityOut, dataContentDescription, description, icons.mIsWide,                mSubscriptionInfo.getSubscriptionId(), mCurrentState.roaming);    }

通过Callback的setMobileDataIndicators方法进行信号状态更新,这里Callback实现类是CallbackHandler

@Override    public void setMobileDataIndicators(final IconState statusIcon, final IconState qsIcon,            final int statusType, final int qsType,final boolean activityIn,            final boolean activityOut, final String typeContentDescription,            final String description, final boolean isWide, final int subId, boolean roaming) {        post(new Runnable() {            @Override            public void run() {                for (SignalCallback signalCluster : mSignalCallbacks) {                    signalCluster.setMobileDataIndicators(statusIcon, qsIcon, statusType, qsType,                            activityIn, activityOut, typeContentDescription, description, isWide,                            subId, roaming);                }            }        });    }

最终通过UI刷新,8.0版本信号显示View是SignalClusterView,9.0变成StatusBarMoboleView.

最后,在这里分享一份本人收集整理的一套Android进阶资料,包含BAT大牛解密Android面试,阿里P7级别架构师进阶资料,热门Android框架解析,大厂高频面试题集锦,CSDN热门开发电子书,LeetCode算法全集视频精讲。




更多相关文章

  1. 关于Handler.removemessages方法
  2. Android(安卓)解决WebView调用loadData()方法显示乱码的问题
  3. AArch64 是什么
  4. android中ListView数据刷新时的同步方法
  5. android 权限permission 说明
  6. iOS和Android对比系列(二):页面跳转和传参
  7. android 图片压缩方法

随机推荐

  1. Android windowSoftInputMode属性解析
  2. mapView 和textView布局
  3. Android 中文 API (100) —— ScrollView
  4. android---------ndk中的各个版本的下载
  5. android原生音乐播放器界面字体显示不全
  6. android开发之Seekbar
  7. android intent的常用方法
  8. ionic build android 结果卡在下载gradle
  9. [Android]在Android google Map中標出自
  10. Android下各文件方法获取的路径