OOBE是开机向导,普通的理解就是一个界面跳另一个界面再跳下一个界面,OOBE却不是这么实现的。下面分析OOBE界面跳转实现:

打开OOBE目录,找到入口是WizardActivity.java,该Activity随后跳转到MainActivity.java。OOBE界面跳转逻辑都在MainActivity.java里实现。

对于一个陌生的Activity,我们先看它的onCreate方法:

@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.i("xsslog","OOBE MainActivity onCreate() ----------111");  this.getWindow().setFlags(FLAG_HOMEKEY_DISPATCHED, FLAG_HOMEKEY_DISPATCHED);//forbid homeKeymSimExist = 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 lzpstate = 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 lzpboolean noIphoneChars = "1".equals(SystemProperties.get("ro.cenon_setting_no_iPhone"));//added by lzpboolean switchPagesByLogo = "1".equals(SystemProperties.get("cenon.switch_oobe_pages_by_logo"));//added by lzpXlog.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 10mStepActivityies.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() {@Overridepublic 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);

@Overridepublic 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进行统一跳转,而不是从当前界面直接往下跳。

@Overrideprotected 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 10mCurrentStep++;nextActivity(true);break;case Utils.RESULT_CODE_TO_TWO_STEP:// add by csc for ios 10mCurrentStep=mCurrentStep+2;nextActivity(true);break;case Utils.RESULT_CODE_TO_LOGIN_ICLOUD:// add by csc for ios 10intent = 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 10intent = 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 10intent = new Intent();intent.setClass(MainActivity.this,OobeForgetAppleIDActivity.class);startActivityForResult(intent, 1001);break;case Utils.RESULT_CODE_TO_NO_STEP:// add by csc for ios 10mCurrentStep--;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的界面跳转。

android 开机向导OOBE源码分析相关推荐

  1. Android Camera 系统架构源码分析

    Android Camera 系统架构源码分析(1)---->Camera的初始化 Android Camera 系统架构源码分析(2)---->Camera的startPreview和s ...

  2. Android 系统(78)---《android framework常用api源码分析》之 app应用安装流程

    <android framework常用api源码分析>之 app应用安装流程 <android framework常用api源码分析>android生态在中国已经发展非常庞大 ...

  3. Android 11.0 Settings源码分析 - 主界面加载

    Android 11.0 Settings源码分析 - 主界面加载 本篇主要记录AndroidR Settings源码主界面加载流程,方便后续工作调试其流程. Settings代码路径: packag ...

  4. Android录音下————AudioRecord源码分析

    Android录音下----AudioRecord源码分析 文章目录 Android录音下----AudioRecord源码分析 一.概述 1.主要分析点 2.储备知识 二.getMinBufferS ...

  5. Android上百实例源码分析以及开源分析集合打包

    感谢网友banketree的收集,压缩包的内容如下: 1.360新版特性界面源代码 实现了360新版特性界面的效果,主要涉及到Qt的一些事件处理与自定义控件.但源码好像是c++. 2.aidl跨进程调 ...

  6. Android 8.0系统源码分析--Camera processCaptureResult结果回传源码分析

    相机,从上到下概览一下,真是太大了,上面的APP->Framework->CameraServer->CameraHAL,HAL进程中Pipeline.接各种算法的Node.再往下的 ...

  7. Android 双开沙箱 VirtualApp 源码分析(一)

    最近发现了一个非常好的开源项目,基本实现了一个 Android 上的沙箱环境,不过应用场景最多的还是应用双开. VA github: https://github.com/asLody/Virtual ...

  8. Android 双开沙箱 VirtualApp 源码分析(六)ContentProvider

    上一章:Android 双开沙箱 VirtualApp 源码分析(五)BroadcastReceiver Provider 注册 回顾前面,Activity 启动的时候会检查 Application ...

  9. Android 双开沙箱 VirtualApp 源码分析(二)

    Android 双开沙箱 VirtualApp 源码分析(二) VA 初始化 先看一下代码: VirtualCore.startup public void startup(Context conte ...

最新文章

  1. frome here on out
  2. 【实战】使用pyecharts绘制词云图-淘宝商品评论展示
  3. MyEclipse中如何设置 jdk 和 jre 编译运行环境
  4. 一步一步学pwntools(适合新手)
  5. HTTP Cookie详解
  6. googlemap 两点间平滑移动_Salomon萨洛蒙徒步登山鞋实测,一双在山林与城市间探索的户外鞋...
  7. junper srx配置思路
  8. golang ide 下载
  9. java 安卓 html文件_使用WebView加载本地html网页文件示例
  10. 苹果库乐队怎么玩_苹果手机如何自定义铃声?这个方法最简单。
  11. PAT日志 1031
  12. 前端基础之浮动个人相册
  13. Core Data 使用
  14. thymeleaf数据回显,单选回填,下拉回填,时间框回填
  15. 利用Matlab判断某些点是否在多边形区域内
  16. android ios av tv,iOS AVPlayerItem
  17. 【分享】国内著名互联网企业PHP笔试题
  18. 免费SIP软交换云总机IPPBX
  19. RHEL8 新特征及使用方法
  20. python获取List数组中重复元素的个数(arcpy中统计FeatureClass中各类型地物要素的图斑数)(地理国情监测)

热门文章

  1. Hp 通过MP卡启动、关闭电源 Hp9000小型机的方式
  2. 为什么要学好c语言,c语言到底多重要,你造吗
  3. deepin linux 2014下载,Deepin 2014官方正式发布下载
  4. 论文解读:SpellBERT:A Lightweight Pretrained Model for Chinese Spelling Checking
  5. SecureCRT提示 not contain an entry for the hostname
  6. 《GitHub入门与实践》读书笔记
  7. 基于WEB信息管理系统测试时应考虑的因素有哪些
  8. 关于PE4259等各类射频开关选型对比分析
  9. Navicat连接oracleTNS无监听程序解决方法
  10. 硬件知识-ADC模数转换芯片