美文网首页Android之网络编程学习
一、Android DcTracker的创建及准备工作

一、Android DcTracker的创建及准备工作

作者: xiabodan | 来源:发表于2017-10-26 18:33 被阅读186次

    DcTracker是在每个Phone构造的时候创建的,DcTrackerBase是DcTracker,他们的核心都是Handler。

    @GSMPhone.java  
    public GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode) {  
        //创建DcTracker对象,传递的参数就是当前的GSMPhone对象  
        mDcTracker = new DcTracker(this);  
    }  
    

    DcTracker作为数据链接中最重要的一个管理者核心,数据链接都会从DcTracker中发起,其中会做一些列的状态检查与判断,DcTracker处于的环节如下图中的浅蓝色部分


    这里写图片描述

    首先看DcTracker的构造

    public DcTracker(PhoneBase p) { 
        super(p);
    
        mDataConnectionTracker = this;
        update();
        mApnObserver = new ApnChangeObserver();
        p.getContext().getContentResolver().registerContentObserver(
                Telephony.Carriers.CONTENT_URI, true, mApnObserver);
    
        initApnContexts();
    
        for (ApnContext apnContext : mApnContexts.values()) {
            // Register the reconnect and restart actions.
            IntentFilter filter = new IntentFilter();
            filter.addAction(INTENT_RECONNECT_ALARM + '.' + apnContext.getApnType());
            filter.addAction(INTENT_RESTART_TRYSETUP_ALARM + '.' + apnContext.getApnType());
            mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
        }
    
        // Add Emergency APN to APN setting list by default to support EPDN in sim absent cases
        initEmergencyApnSetting();
        addEmergencyApnSetting();
    
        mProvisionActionName = "com.android.internal.telephony.PROVISION" + p.getPhoneId();
    }    
    

    首先调用的是update(),这里注册了大量的监听事件,并注册了APN参数的监听器

    public void update() {  
         if (isActiveDataSubscription()) {  
             //注册各种监听器  
             registerForAllEvents(); 
             //注册SIM卡状态监听器  
             onUpdateIcc();
             //mUserDataEnabled就是用户是否打开网络开关的标志位,当为0时,表示当前数据流量被关闭  
             mUserDataEnabled = Settings.Global.getInt(mPhone.getContext().getContentResolver(), Settings.Global.MOBILE_DATA, 1) == 1;  
         }
     }   
    

    接下来继续来看registerForAllEvents()和onUpdateIcc()中注册的事件类型

    protected void registerForAllEvents() {  
        //监听射频是否打开,没有处理动作  
        mPhone.mCi.registerForAvailable(this, DctConstants.EVENT_RADIO_AVAILABLE, null);  
        //监听射频是否可用,没有处理动作  
        mPhone.mCi.registerForOffOrNotAvailable(this, DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);  
        //监听当前连接状态,没有处理动作  
        mPhone.mCi.registerForDataNetworkStateChanged(this, DctConstants.EVENT_DATA_STATE_CHANGED, null);  
        //监听当前通话状态,没有处理动作  
        mPhone.getCallTracker().registerForVoiceCallEnded (this, DctConstants.EVENT_VOICE_CALL_ENDED, null);  
        //监听当前通话状态,没有处理动作  
        mPhone.getCallTracker().registerForVoiceCallStarted (this, DctConstants.EVENT_VOICE_CALL_STARTED, null);  
        //监听是否PS域Attach状态  
        mPhone.getServiceStateTracker().registerForDataConnectionAttached(this, DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);  
        //监听是否PS域Detach状态  
        mPhone.getServiceStateTracker().registerForDataConnectionDetached(this, DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);  
        //监听漫游状态,没有处理动作  
        mPhone.getServiceStateTracker().registerForRoamingOn(this, DctConstants.EVENT_ROAMING_ON, null);  
        //监听漫游状态,没有处理动作  
        mPhone.getServiceStateTracker().registerForRoamingOff(this, DctConstants.EVENT_ROAMING_OFF, null);  
        mPhone.getServiceStateTracker().registerForPsRestrictedEnabled(this, DctConstants.EVENT_PS_RESTRICT_ENABLED, null);  
        mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this, DctConstants.EVENT_PS_RESTRICT_DISABLED, null);  
        //监听接入技术状态  
        mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(this, DctConstants.EVENT_DATA_RAT_CHANGED, null);  
    }  
    
    

    registerForAllEvents()注册了大量的事件,但是其中最重要的事件是EVENT_DATA_CONNECTION_ATTACHED
    ----监听PS的Attach事件(代码中看出来应该是DataRegState的状态由STATE_OUT_OF_SERVICE -> STATE_IN_SERVICE),触发时将进入onDataConnectionAttached()

    protected void onUpdateIcc() {  
       if (mUiccController == null ) {  
           return;  
       }  
       IccRecords newIccRecords = getUiccRecords(UiccController.APP_FAM_3GPP);  
       IccRecords r = mIccRecords.get();  
       if (r != newIccRecords) {  
           if (r != null) {  
               r.unregisterForRecordsLoaded(this);  
               mIccRecords.set(null);  
           }  
           if (newIccRecords != null) {  
               mIccRecords.set(newIccRecords);  
               //监听SIM各项数据是否载入完毕  
               newIccRecords.registerForRecordsLoaded( this, DctConstants.EVENT_RECORDS_LOADED, null);  
           }  
       }  
    }  
    

    其中注册了EVENT_RECORDS_LOADED事件,这个事件在SIM卡被装载完成后被通知
    紧接着在DcTracker的构造中注册了APN参数变化的监听器,在用户手动切换选择APN时这个监听器会相应,将当前的APN参数更新为用户选择的APN参数

    mApnObserver = new ApnChangeObserver();
    p.getContext().getContentResolver().registerContentObserver(
    Telephony.Carriers.CONTENT_URI, true, mApnObserver);

    接下来在initApnContexts()中会初始化好当前系统支持的ApnContexts类型,并增加紧急APN,至此DcTracker的构造就完成了,在DcTrackerBase中还会创建一些与DataConnection有关的对象,接下来看DcTrackerBase的构造内容

    protected DcTrackerBase(PhoneBase phone) {
        super();
        mPhone = phone;
        mResolver = mPhone.getContext().getContentResolver();
        mUiccController = UiccController.getInstance();
        mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
        mAlarmManager =
                (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
        mCm = (ConnectivityManager) mPhone.getContext().getSystemService(
                Context.CONNECTIVITY_SERVICE);   //拿到ConnectivityManager
    
        mUserDataEnabled = getDataEnabled();
    
        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone); 
    
        HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
        dcHandlerThread.start();
        Handler dcHandler = new Handler(dcHandlerThread.getLooper());
        mDcc = DcController.makeDcc(mPhone, this, dcHandler);
        mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
    }
    

    其中mResolver = mPhone.getContext().getContentResolver();是拿到ContentResolver,查询数据库就是通过这个对象去操作的,比如后面的mUserDataEnabled = getDataEnabled();
    mUserDataEnabled是保存在settings.db数据库中表global中的mobile_data字段

    public boolean getDataEnabled() {
        boolean retVal = "true".equalsIgnoreCase(SystemProperties.get(
                "ro.com.android.mobiledata", "true"));
        try {
            if (TelephonyManager.getDefault().getSimCount() == 1) {  //单卡path
                retVal = Settings.Global.getInt(mResolver, Settings.Global.MOBILE_DATA,
                        retVal ? 1 : 0) != 0;
            } else {
                int phoneSubId = mPhone.getSubId();                  //多卡path
                retVal = TelephonyManager.getIntWithSubId(mResolver, Settings.Global.MOBILE_DATA,
                        phoneSubId) != 0;
            }
            if (DBG) log("getDataEnabled: getIntWithSubId retVal=" + retVal);
        } 
        return retVal;
    }
    

    顺便提一下这个字段(settings.db数据库中表global中的mobile_data字段)的更新在DcTrackerBase.java中的onSetUserDataEnabled(boolean enabled)

    protected void onSetUserDataEnabled(boolean enabled) {
        if (TelephonyManager.getDefault().getSimCount() == 1) {
            Settings.Global.putInt(mResolver, Settings.Global.MOBILE_DATA, enabled ? 1 : 0);
        } else {
             int phoneSubId = mPhone.getSubId();
             Settings.Global.putInt(mResolver, Settings.Global.MOBILE_DATA + phoneSubId,
                    enabled ? 1 : 0);
        }
    }
    

    其中 mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);注册EVENT_ICC_CHANGED事件,当SIM卡发生改变时触发
    其中 mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone); 注册一些Intent事件,比如当手机屏幕关闭时,就会关闭数据上下行的统计,等等
    接下来是比较重要的一部分,在这里只是new HandlerThread,并创建了一个新的Handler放入DcController,创建了DcController对象,在后续中还会仔细分析这个Handler

        HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
        dcHandlerThread.start();
        Handler dcHandler = new Handler(dcHandlerThread.getLooper());
        mDcc = DcController.makeDcc(mPhone, this, dcHandler);
        mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
    

    至此,DcTracker算是完成了构造过程,接下来分析数据链接的动态过程

    相关文章

      网友评论

        本文标题:一、Android DcTracker的创建及准备工作

        本文链接:https://www.haomeiwen.com/subject/iwnkpxtx.html