android 開機嚮導OOBE源碼分析

OOBE是開機嚮導,普通的理解就是一個界面跳另一個界面再跳下一個界面,OOBE卻不是這麼實現的。下面分析OOBE界面跳轉實現:

打開OOBE目錄,找到入口是WizardActivity.java,該Activity隨後跳轉到MainActivity.java。OOBE界面跳轉邏輯都在MainActivity.java裏實現。

對於一個陌生的Activity,我們先看它的onCreate方法:

@Override
    public void onCreate(Bundle savedInstanceState) {
 
        super.onCreate(savedInstanceState);


	 Log.i("xsslog","OOBE MainActivity onCreate() ----------111");	
	 this.getWindow().setFlags(FLAG_HOMEKEY_DISPATCHED, FLAG_HOMEKEY_DISPATCHED);//forbid homeKey
        mSimExist = isSimExist();
        Xlog.d(TAG, "onCreate mSimExist = " + mSimExist);


        if (savedInstanceState != null) {
            mCurrentStep = savedInstanceState.getInt("currentStep");
            mTotalStep = savedInstanceState.getInt("totalSteps");
            Log.i("xsslog", "restore saved instance state mCurrentStep=" + mCurrentStep + "mTotalStep="
                    + mTotalStep);
            setActivityList();
        }
        
        //Diable window rotate for phone.  
        setWindowRotation(false);
        //disable quick start guide for tablet
        //disableQSG();
        
        mIsFirstRun = Settings.System.getInt(getContentResolver(), Utils.OOBE_HAS_RUN_KEY, 0) == 0; 
	Log.i("xsslog","OOBE MainActivity onCreate() -----222-----mIsFirstRun="+mIsFirstRun);	
        if (mIsFirstRun) {
            Settings.System.putInt(getContentResolver(),
                Settings.System.OOBE_DISPLAY, Settings.System.OOBE_DISPLAY_ON);
            Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0);
            enableStatusBar(false);
        }


        mBootMode = getBootMode();      


	
        if (mIsFirstRun && mBootMode != BOOT_MODE_ADV_META && !Utils.isWifiOnly(this)) {
             mHandler.sendEmptyMessageDelayed(EVENT_MONITOR_SIM_TIME_OUT, TIME_MONITOR_SIM);
	      Log.i("xsslog","OOBE MainActivity ()=========");		 
            //showDialog(DIALOG_WAITING_SIM);
        } else {
            mHandler.sendEmptyMessage(EVENT_SIM_DETECTING_READY);
        }
        
        
        mSIMIntentFilter = new IntentFilter(TelephonyIntents.ACTION_SIM_INFO_UPDATE);
        registerReceiver(mSIMStateReceiver, mSIMIntentFilter);
	 
	 pm = getPackageManager();
        name = new ComponentName(this, WizardActivity.class);
		if(pm != null)//added by lzp
        	state = pm.getComponentEnabledSetting(name);
/*	  mVelocityTracker = VelocityTracker.obtain();
        mScreenOffReceiverFilter = new IntentFilter();
	 mScreenOffReceiverFilter.addAction(Intent.ACTION_SCREEN_ON);
	 registerReceiver(mScreenOffReceiver,mScreenOffReceiverFilter);
	 
*/      
    }
其中mCurrentStep是指當前界面數,mTotalStep是指OOBE總界面數。mIsFirstRun判斷是否第一次進入OOBE,做相應處理

這裏的重點是看setActivityList();

protected void setActivityList() {
	 boolean mIphoneFlag = Settings.System.getInt(this.getContentResolver(), Settings.System.ISIPHONE, 0) == 1;//added by lzp
	 boolean noIphoneChars = "1".equals(SystemProperties.get("ro.cenon_setting_no_iPhone"));//added by lzp
	 boolean switchPagesByLogo = "1".equals(SystemProperties.get("cenon.switch_oobe_pages_by_logo"));//added by lzp
		 Xlog.d(TAG, "setActivityList() mIphoneFlag="+mIphoneFlag);
     mStepActivityies.clear();
	
	 if((!switchPagesByLogo && !noIphoneChars) || mIphoneFlag) {
		 mStepActivityies.add(mLanguageSettings);
		 mStepActivityies.add(mCountrySettings);
		 mStepActivityies.add(iMessageAndFaceTime);// add by csc for ios 10
		 mStepActivityies.add(mInputMethodSettings);
		 mStepActivityies.add(mWifiSettings);	
		 mStepActivityies.add(mfinishOobe);
	 } else {//added by lzp 
		 mStepActivityies.add(mLanguageSettings);
		 mStepActivityies.add(mCountrySettings);
		 mStepActivityies.add(mInputMethodSettings);
		 mStepActivityies.add(mfinishOobe);
	 }
     mTotalStep = mStepActivityies.size();
    }

可以看到每個界面都被加到了mStepActivityies裏面,mTotalStep就是在這裏得出

private List<OobeActivityInfo> mStepActivityies = new ArrayList<OobeActivityInfo>();
我們發現裏面有個mHandler處理,於是我們跳到該mHandler:

private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
            case EVENT_MONITOR_SIM_TIME_OUT:
                Xlog.v(TAG, "handler wait SIM time out");
                break;
            case EVENT_SIM_DETECTING_READY:
                Xlog.v(TAG, "handler SIM initialization finish");
                mHandler.removeMessages(EVENT_MONITOR_SIM_TIME_OUT);
                break;			
	     case EVENT_PREPAREING_END_OOBE:
		   mHandler.removeMessages(EVENT_PREPAREING_END_OOBE);
		   finish();
                break;	
	     default:
                break;
            }
            initStep();
            //removeDialog(DIALOG_WAITING_SIM);
        };
    };
可以看到有EVENT_MONITOR_SIM_TIME_OUT,EVENT_SIM_DETECTING_READY,EVENT_PREPAREING_END_OOBE等情況的處理,我們主要研究OOBE界面是如何進行跳轉的,上面的就不細做分析了。然後就注意到initStep()方法
private void initStep() {       
        if (mIsStepInitiated) {
            return;
        }
        mIsStepInitiated = true;
        setActivityList();

        if (mCurrentStep == -1) {
            nextActivity(true);
        }
    }
setActivityList()上面說了把界面都放入list,重點看nextActivity方法
protected void nextActivity(boolean nextStep) {     
        if (nextStep) {
		if(mCurrentStep<0)
		 {
			 mCurrentStep++;
			 Intent lockScreenIntent = new Intent(ACTION_LOCK_SCREEN);
			 startActivityForResult(lockScreenIntent, REQUEST_CODE_ADVANCED_SETTINGS);
			 return;
		 }
            else mCurrentStep++;
        } else {
            mCurrentStep--;
        }
     
	
        if (mCurrentStep >= 0 && mCurrentStep < mStepActivityies.size()) {

            Intent intent = mStepActivityies.get(mCurrentStep).getIntent();
            intent.putExtra(Utils.OOBE_BASIC_STEP_TOTAL, mTotalStep);
            intent.putExtra(Utils.OOBE_BASIC_STEP_INDEX, mCurrentStep + 1);
            intent.putExtra(EXTRA_IS_OOBE, true);
            startActivityForResult(intent, mCurrentStep);

            if (nextStep) {
		   overridePendingTransition(R.anim.slide_right_in, R.anim.slide_left_out);
                //overridePendingTransition(R.anim.zoomin, R.anim.zoomout);
            } else {
                 overridePendingTransition(R.anim.slide_left_in, R.anim.slide_right_out);
                 //overridePendingTransition(R.anim.zoomin, R.anim.zoomout);
            }
        }
    }
nextStep用來判斷下一步還是上一步,mCurrentStep是要跳轉界面的值,知道這個前一部分代碼就好理解了
Intent intent = mStepActivityies.get(mCurrentStep).getIntent();
            intent.putExtra(Utils.OOBE_BASIC_STEP_TOTAL, mTotalStep);
            intent.putExtra(Utils.OOBE_BASIC_STEP_INDEX, mCurrentStep + 1);
            intent.putExtra(EXTRA_IS_OOBE, true);
            startActivityForResult(intent, mCurrentStep);
根據mCurrentStep從mStepActivityies取出該界面的包名,用startActivityForResult方法進行跳轉,我們可以看下回傳的參數用來幹嘛

其他界面點擊上一步或者下一步的時候就調用finishActivityByResult(Utils.RESULT_CODE_TO_NO_STEP);

@Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.back_settings_btn:
                finishActivityByResult(Utils.RESULT_CODE_TO_NO_STEP);
                break;
            case R.id.next_settings_btn:
              /*  Intent intent = new Intent();
                intent.setClass(OobeLoginiCloudActivity.this,OobeTermsAndConditionsActivity.class);
                intent.putExtra("GOTO_BY_ICLOUD",true);
                startActivity(intent);
                finish();*/
                finishActivityByResult(Utils.RESULT_CODE_TO_TWO_STEP);
                break;
        }
    }
 private void finishActivityByResult(int resultCode) {
        Intent intent = new Intent();
        setResult(resultCode, intent);
        finish();
    }
然後把這個是跳上一步還是下一步傳回MainActivity,由MainActivity進行統一跳轉,而不是從當前界面直接往下跳。


@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        Xlog.d(TAG, "onActivityResult resultCode = " + resultCode);
        switch (resultCode) {
            case Utils.RESULT_CODE_BACK:
                if (0 == mCurrentStep) {
                    finish();
                } else {
                    nextActivity(false);
                }
                break;
            case Utils.RESULT_CODE_NEXT:
                nextActivity(true);
                break;
            case Utils.RESULT_CODE_FINISH:
                finishOOBE();
                break;
            case Utils.RESULT_CODE_TO_ONE_STEP:// add by csc for ios 10
                mCurrentStep++;
                nextActivity(true);
                break;
            case Utils.RESULT_CODE_TO_TWO_STEP:// add by csc for ios 10
                mCurrentStep=mCurrentStep+2;
                nextActivity(true);
                break;
            case Utils.RESULT_CODE_TO_LOGIN_ICLOUD:// add by csc for ios 10
                intent = new Intent();
                intent.setClass(MainActivity.this,OobeLoginiCloudActivity.class);
                startActivityForResult(intent, 1001);
                break;
            case Utils.RESULT_CODE_TO_FORGET_PASSWORD:
                intent = new Intent();
                intent.setClass(MainActivity.this,OobeForgetPasswordActivity.class);
                startActivityForResult(intent, 1001);
                break;
            case Utils.RESULT_CODE_TO_CREATE_APPLE_ID:// add by csc for ios 10
                intent = new Intent();
                intent.setClass(MainActivity.this,OobeCreateAppleIdActivity.class);
                startActivityForResult(intent, 1001);
                break;
            case Utils.RESULT_CODE_TO_FORGET_APPLE_ID:// add by csc for ios 10
                intent = new Intent();
                intent.setClass(MainActivity.this,OobeForgetAppleIDActivity.class);
                startActivityForResult(intent, 1001);
                break;
            case Utils.RESULT_CODE_TO_NO_STEP:// add by csc for ios 10
                mCurrentStep--;
                nextActivity(true);
                break;
	     case 100:
              {
				 /**Begin: added by lzp **/
				if(mCurrentStep < 0) {
					mHandler.sendEmptyMessage(EVENT_SIM_DETECTING_READY);
					return;
				 }
				 /**End: added by lzp **/
                 Intent backIntent = mStepActivityies.get(mCurrentStep).getIntent();
                 backIntent.putExtra(Utils.OOBE_BASIC_STEP_TOTAL, mTotalStep);
                 backIntent.putExtra(Utils.OOBE_BASIC_STEP_INDEX, mCurrentStep + 1);
                 backIntent.putExtra(EXTRA_IS_OOBE, true);
                 startActivityForResult(backIntent, mCurrentStep);
		    overridePendingTransition(R.anim.slide_left_in, R.anim.slide_right_out);
		    //overridePendingTransition(R.anim.zoomin, R.anim.zoomout);
		 }
                break;
            case Utils.RESULT_SCREEN_OFF:
                {
			Intent lockScreenIntent = new Intent(ACTION_LOCK_SCREEN);
		        startActivityForResult(lockScreenIntent, REQUEST_CODE_ADVANCED_SETTINGS);
			 overridePendingTransition(R.anim.slide_left_in, R.anim.slide_right_out);	
		         //overridePendingTransition(R.anim.zoomin, R.anim.zoomout);
			}
                break;
            default:
                break;
        }
    }

到這裏就完成了OOBE的界面跳轉。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章