当我们在Launcher中点击浏览器的图标时,浏览器的窗口会打开并显示主页(HomePage)。这里我们对这一场景进行分析,研究浏览器如何启动,取得缺省主页并将它布局和显示的。

根据前边对WebView 类的学习,大概可以预期我们在主Activity的onCreate方法里从设置里面取得缺省主页的配置,创建一个WebView类,并使用setContentView将它添加到主窗口中。下面我们从浏览器的代码看看它是如何实现的。

首先,研究AndroidManifest文件,从<application>标签的内容看到该Apk实现了自己的Applicaton 类Browser:

<application   android:name="Browser"android:label="@string/application_name"android:icon="@mipmap/ic_launcher_browser"android:backupAgent=".BrowserBackupAgent"android:hardwareAccelerated="true"android:taskAffinity="android.task.browser" >

另外,该Apk的主Activity为BrowserActivity:

<activity android:name="BrowserActivity"android:label="@string/application_name"android:launchMode="singleTask"android:alwaysRetainTaskState="true"android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"android:theme="@style/BrowserTheme"android:windowSoftInputMode="adjustResize" >

。。。

<!-- We are also the main entry point of the browser. -->
<intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.LAUNCHER" /><category android:name="android.intent.category.BROWSABLE" /><category android:name="android.intent.category.APP_BROWSER" />
</intent-filter>

Apk的启动,首先是ApplicationBrowser类的onCreate方法,主要工作:

// create CookieSyncManager with current Context

CookieSyncManager.createInstance(this);

BrowserSettings.initialize(getApplicationContext());

Preloader.initialize(getApplicationContext());

这里涉及到三个工作:Cookie同步管理,浏览器设置和预加载。

然后是Activity的onCreate方法,与我们的研究相关的代码:

@Override
public void onCreate(Bundle icicle) {if (LOGV_ENABLED) {Log.v(LOGTAG, this + " onStart, has state: "+ (icicle == null ? "false" : "true"));}super.onCreate(icicle);mController = createController();Intent intent = (icicle == null) ? getIntent() : null;mController.start(intent);
}

createController方法:

private Controller createController() {Controller controller = new Controller(this);boolean xlarge = isTablet(this);UI ui = null;if (xlarge) {ui = new XLargeUi(this, controller);} else {ui = new PhoneUi(this, controller);}controller.setUi(ui);return controller;
}

主要的工作是Controller的创建,PhoneUi的创建和Controller的start。

Controller的构造方法主要涉及到以下几个相关类:

BrowserSettings

TabControl

CrashRecoveryHandler

UrlHandler

BrowserWebViewFactory

IntentHandler

PageDialogHandler

BookMarks的ContentObserver

NetworkStateHandler

SystemAllowGeolocationOrigins

IconDataBase

PhoneUi的构造:

BaseUi的构造:

FrameLayout frameLayout = (FrameLayout) mActivity.getWindow().getDecorView().findViewById(android.R.id.content);
LayoutInflater.from(mActivity).inflate(R.layout.custom_screen, frameLayout);
mFixedTitlebarContainer = (FrameLayout) frameLayout.findViewById(R.id.fixed_titlebar_container);
mContentView = (FrameLayout) frameLayout.findViewById(R.id.main_content);
mCustomViewContainer = (FrameLayout) frameLayout.findViewById(R.id.fullscreen_custom_content);
mErrorConsoleContainer = (LinearLayout) frameLayout.findViewById(R.id.error_console);

Custom_screen的layout文件:

<mergexmlns:android="http://schemas.android.com/apk/res/android"><FrameLayout android:id="@+id/fullscreen_custom_content"android:visibility="gone"android:background="@color/black"android:layout_width="match_parent"android:layout_height="match_parent"/><com.android.browser.view.CustomScreenLinearLayoutandroid:orientation="vertical"android:id="@+id/vertical_layout"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayout android:id="@+id/error_console"android:layout_width="match_parent"android:layout_height="wrap_content"/><FrameLayout android:id="@+id/fixed_titlebar_container"android:layout_width="match_parent"android:layout_height="wrap_content"/><FrameLayout android:id="@+id/main_content"android:layout_width="match_parent"android:layout_height="match_parent"/></com.android.browser.view.CustomScreenLinearLayout>
</merge>

可以看出这个是浏览器主界面的布局,浏览器的布局已经准备好,后面我们创建的WebView应该是添加到main_content里面。

Controller 的start 方法执行了CrashRecoveryHandler的startRecovery().

CrashRecoveryHandler相关操作:

首先是initialize(),创建了CrashRecoveryHandler实例,CrashRecoveryHandler实例构造了foregroundHandler和backgroundHandler。

CrashRecoveryHandler的preloadCrashState方法,在backgroundHandler的处理中执行loadCrashState(),该方法将CrashState从STATE_FILE读入到mRecoveryState中。

CrashRecoveryHandler的startRecovery方法,调用Controller的doStart()。

Controller的doStart方法调用onPreloginFinished().

currentTabId is -1, thenopenTabToHomePage().

openTabToHomePage

createNewTabthen loadUrl.

createNewTab的实现:

TabControl::createNewTab

createNewWebView:

new BrowserWebView;该类主要用来管理WebView滚动条事件。

initWebViewSettings;

setActiveTab

TabControl::setCurrentTab

PhoneUi::setActiveTab

attachTabToContentView

至此,我们看完Apk启动并加载HomePage的过程,简单总结如下:

1.浏览器实现了自己的Application类(Browser),在其onCreate方法中进行了一些初始化工作(Cookie同步管理,浏览器设置和预加载);

2.浏览器的主Activity是BrowserActivity,在其onCreate方法中构建了Controller和PhoneUi,并调用Controller::start方法启动Controller;

a)Controller在其构造方法中实例化和初始化一些协助对象,其中一个重要的类是CrashRecoveryHandler;

b)PhoneUi的构造方法加载custom_screen布局文件,并将它作为Activity窗口的ContentView.

c)Controller::start方法执行了CrashRecoveryHandler的startRecovery(),该方法又调用Controller的doStart()方法

i.Controller的doStart方法调用onPreloginFinished(),该方法执行openTabToHomePage,打开浏览器主页。具体将WebView加到ContentView的方法是BaseUi的attachTabToContentView方法。

转载于:https://blog.51cto.com/sunhongbo/1357127

Android 浏览器的研究(四)--- Apk的启动和主页的加载过程相关推荐

  1. linux内核启动以及文件系统的加载过程

    Linux 内核启动及文件系统加载过程 当u-boot 开始执行 bootcmd 命令,就进入 Linux 内核启动阶段.普通 Linux 内核的启动过程也可以分为两个阶段.本文以项目中使用的 lin ...

  2. android反射开启通知_作为Android开发者 你真的知道app从启动到主页显示的过程吗?...

    前言 之前我跟大家说过,在一个夜黑风高的晚上,我的男同事突然给我发了一条微信,我点开来看,他竟然问我Android从按下开机键到启动到底发生了什么?此刻我的内心如下图: 然后就在昨天晚上,我又收到了他 ...

  3. 【SemiDrive源码分析】【X9芯片启动流程】27 - AP1 Android Preloader启动流程分析(加载atf、tos、bootloader镜像后进入BL31环境)

    [SemiDrive源码分析][X9芯片启动流程]27 - AP1 Android Preloader启动流程分析(加载atf.tos.bootloader镜像后进入BL31环境) 一.Android ...

  4. 【Android 应用开发】UI绘制流程 ( 生命周期机制 | 布局加载机制 | UI 绘制流程 | 布局测量 | 布局摆放 | 组件绘制 | 瀑布流布局案例 )

    文章目录 一. 博客相关资料 及 下载地址 1. 代码查看方法 ( ① 直接获取代码 | ② JAR 包替换 ) 2. 本博客涉及到的源码查看说明 二. Activity 生命周期回调机制 1. An ...

  5. Android插件化学习之路(一)之动态加载综述

    前段时间,公司项目完成了插件化的开发,自己也因此学习了很多Android插件化的知识,于是想把这些内容记录下来,本次带来Android插件化的第一篇:动态加载综述 Android插件化学习之路(一)之 ...

  6. 你所不知道的SQL Server数据库启动过程(用户数据库加载过程的疑难杂症)

    转http://www.cnblogs.com/zhijianliutang/p/4100103.html 前言 本篇主要是上一篇文章的补充篇,上一篇我们介绍了SQL Server服务启动过程所遇到的 ...

  7. 浏览器页面资源加载过程与优化

    评价页面性能好坏的核心之一就是页面的加载速度,而页面加载速度的关键就是页面资源的加载.本文将从浏览器浏览器页面资源加载过程展开分析,来引出页面关键请求路径的概念,并给出如何优化该关键请求路径的一些方法 ...

  8. android应用加载过程中的loading动画

    应用加载过程中的loading动画: LoadingView .java /***  * loading 动画的实现  * @author   *  */ public class LoadingVi ...

  9. 配置项目启动的时候就加载 servlet

    load-on-startup值为0 就是在项目启动的时候自动加载该servlet

最新文章

  1. R语言使用ggpubr包可视化分组条形图(grouped bar plot)、并添加误差条(error bar、误差条显示平均值+/-sd)、添加分组填充色、添加jitter、自定义分组抖动数据点形状
  2. 归并排序执行次数_归并排序过程、时间复杂度分析及改进
  3. stopstart按钮怎么用_烟雾报警器一直响吵人!怎么彻底给关掉?
  4. JVM详解之:汇编角度理解本地变量的生命周期
  5. Android官方开发文档Training系列课程中文版:添加ActionBar之ActionBar浮层效果
  6. 吉林建筑大学计算机科学技术,魏立明 - 吉林建筑大学 - 电气与计算机学院
  7. IP地址 0.0.0.0 是什么意思?
  8. 全网首发!超全SparseR-CNN实战教程
  9. 【2012 - 百度之星资格赛 - H:用户请求中的品牌】
  10. Python 中的闭包
  11. Python实战——为人脸照片添加口罩
  12. HTTP接口的请求参数类型有哪些
  13. 串口收 程序FPGA
  14. RocketMQ(10)——发送延时消息
  15. python中使用缩进来体现代码之间的逻辑关系_Python使用缩进来体现代码之间的逻辑关系....
  16. 3825. 逃离大森林
  17. 600道计算机二级python选择题在线真题题库
  18. 外贸:掌握这5个社交软件,让你不在为营销推广感到烦恼
  19. React+Redux技术栈核心要点解析(下篇)
  20. SAP 成本中心和内部订单浅析

热门文章

  1. python 函数复习
  2. package.json中dependencies 与devDependencies 的区别
  3. CentOs配置网卡
  4. TCP/IP报文格式
  5. jquery之empty()与remove([expr])区别
  6. 自定义控件例如LinearLayout 的三种方法
  7. php mysql事务处理回滚操作
  8. 字典树(trie树)、后缀树
  9. 腾讯面试:bitmap统计元素出现次数,使用较少内存
  10. docker搭建常见组件