Android U Settings 应用中 APN 菜单实现的代码逻辑

功能简介

MobileNetwork移动网络设置页面下有【接入点设置】(APN)。

问题:为什么Controller初始化找不到pref,然后报错。

Note:什么时候切换成Controller的呢?在Android T&U 上还没有更新成kt实现 ,但是已经有Controller的方案。

流程逻辑

1、界面“telephony_apn_key” 绑定 “ApnPreferenceController”

        <com.android.settingslib.RestrictedPreference
            android:key="telephony_apn_key"
            android:persistent="false"
            android:title="@string/mobile_network_apn_title"
            settings:allowDividerAbove="true"
            settings:keywords="@string/keywords_access_point_names"
            settings:controller="com.android.settings.network.telephony.ApnPreferenceController"/>

2、加载UI时,“MobileNetworkSettings” -- onAttach --  use(Controller).init(subId)

  use(ApnPreferenceController.class).init(mSubId);

就是此处异常,无法创建ApnPreferenceController对象实例。

Note:use是什么逻辑?

关于界面刷新

MobileNetworkSettings类控制着移动网络设置的各个菜单显示逻辑,

onAvailableSubInfoChanged -- MobileNetworkRepository的回调

onSubscriptionDetailChanged -- 更新标题并刷新控件

redrawPreferenceControllers -- 开线程,在主线程更新UI,由父类实现

通过 ThreadUtils.postOnMainThread() 保证在主线程刷新界面,redrawPreferenceControllers 重新绘制/更新屏幕上的菜单控件。

ThreadUtils.postOnMainThread(() -> {
    renameTitle.accept(getActivity());
    redrawPreferenceControllers();
});

代码详情

业务代码和日志案例

 mobile_network_settings 布局

packages/apps/Settings/res/xml/mobile_network_settings.xml

定义移动网络界面的菜单控件,以供MobileNetwork渲染使用。

<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:settings="http://schemas.android.com/apk/res-auto"
    android:key="mobile_network_pref_screen">

    <PreferenceCategory
        android:key="enabled_state_container"
        android:title="@string/summary_placeholder"
        settings:controller="com.android.settings.network.telephony.DisabledSubscriptionController"
        android:layout="@layout/preference_category_no_label">

        <!--We want separate APN setting from reset of settings because we want user to change it with caution-->
        <com.android.settingslib.RestrictedPreference
            android:key="telephony_apn_key"
            android:persistent="false"
            android:title="@string/mobile_network_apn_title"
            settings:allowDividerAbove="true"
            settings:keywords="@string/keywords_access_point_names"
            settings:controller="com.android.settings.network.telephony.ApnPreferenceController"/>


    </PreferenceCategory>

</PreferenceScreen>


MobileNetworkSettings 界面加载

packages/apps/Settings/src/com/android/settings/network/telephony/MobileNetworkSettings.java

加载界面菜单控件,并响应多种信息回调更新界面,如注册状态变化时,显示或隐藏某些功能菜单。

@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class MobileNetworkSettings extends AbstractMobileNetworkSettings implements
        MobileNetworkRepository.MobileNetworkCallback {

    private static final String LOG_TAG = "NetworkSettings";


    //界面创建时候初始化各菜单的控制器
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        use(ApnPreferenceController.class).init(mSubId);
    }


    //注册状态变化时候,需要更新界面菜单
    private void onSubscriptionDetailChanged() {
        if (mSubscriptionInfoEntity != null) {
            /**
             * Update the title when SIM stats got changed
             */
            final Consumer<Activity> renameTitle = activity -> {
                if (activity != null && !activity.isFinishing()) {
                    if (activity instanceof SettingsActivity) {
                        ((SettingsActivity) activity).setTitle(mSubscriptionInfoEntity.uniqueName);
                    }
                }
            };
        
            //主线程刷新界面
            ThreadUtils.postOnMainThread(() -> {
                renameTitle.accept(getActivity());
                redrawPreferenceControllers();    //父类AbstractMobileNetworkSettings.java方法刷新界面
            });
        }
    }


    @Override
    public void onAvailableSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) {
        Log.d(LOG_TAG,"onAvailableSubInfoChanged+");
        // Check the current subId is existed or not, if so, finish it.
        if (!mSubscriptionInfoMap.isEmpty()) {

            // Check each subInfo and remove it in the map based on the new list.
            for (SubscriptionInfoEntity entity : subInfoEntityList) {
                mSubscriptionInfoMap.remove(Integer.parseInt(entity.subId));
                Log.d(LOG_TAG,"onAvailableSubInfoChanged: remove entity = " + entity);
            }

            Iterator<Integer> iterator = mSubscriptionInfoMap.keySet().iterat
  • 39
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值