SystemUI之——信号显示流程,基于Android P AOSP

上一篇讲到,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 that
have a lifecycle that spans sysui. Dependency has code for how to create all
dependencies manually added. SystemUIFactory is also capable of
adding/replacing these dependencies.

Dependencies are lazily initialized, so if a Dependency is never referenced at
runtime, it will never be created.

If an instantiated dependency implements Dumpable it will be included in dumps
of 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 will
receive 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算法全集视频精讲。
SystemUI之——信号显示流程,基于Android P AOSP_第1张图片
SystemUI之——信号显示流程,基于Android P AOSP_第2张图片
SystemUI之——信号显示流程,基于Android P AOSP_第3张图片
SystemUI之——信号显示流程,基于Android P AOSP_第4张图片
SystemUI之——信号显示流程,基于Android P AOSP_第5张图片

你可能感兴趣的:(Android)