Android 浏览器的研究(四)--- Apk的启动和主页的加载过程
当我们在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的启动和主页的加载过程相关推荐
- linux内核启动以及文件系统的加载过程
Linux 内核启动及文件系统加载过程 当u-boot 开始执行 bootcmd 命令,就进入 Linux 内核启动阶段.普通 Linux 内核的启动过程也可以分为两个阶段.本文以项目中使用的 lin ...
- android反射开启通知_作为Android开发者 你真的知道app从启动到主页显示的过程吗?...
前言 之前我跟大家说过,在一个夜黑风高的晚上,我的男同事突然给我发了一条微信,我点开来看,他竟然问我Android从按下开机键到启动到底发生了什么?此刻我的内心如下图: 然后就在昨天晚上,我又收到了他 ...
- 【SemiDrive源码分析】【X9芯片启动流程】27 - AP1 Android Preloader启动流程分析(加载atf、tos、bootloader镜像后进入BL31环境)
[SemiDrive源码分析][X9芯片启动流程]27 - AP1 Android Preloader启动流程分析(加载atf.tos.bootloader镜像后进入BL31环境) 一.Android ...
- 【Android 应用开发】UI绘制流程 ( 生命周期机制 | 布局加载机制 | UI 绘制流程 | 布局测量 | 布局摆放 | 组件绘制 | 瀑布流布局案例 )
文章目录 一. 博客相关资料 及 下载地址 1. 代码查看方法 ( ① 直接获取代码 | ② JAR 包替换 ) 2. 本博客涉及到的源码查看说明 二. Activity 生命周期回调机制 1. An ...
- Android插件化学习之路(一)之动态加载综述
前段时间,公司项目完成了插件化的开发,自己也因此学习了很多Android插件化的知识,于是想把这些内容记录下来,本次带来Android插件化的第一篇:动态加载综述 Android插件化学习之路(一)之 ...
- 你所不知道的SQL Server数据库启动过程(用户数据库加载过程的疑难杂症)
转http://www.cnblogs.com/zhijianliutang/p/4100103.html 前言 本篇主要是上一篇文章的补充篇,上一篇我们介绍了SQL Server服务启动过程所遇到的 ...
- 浏览器页面资源加载过程与优化
评价页面性能好坏的核心之一就是页面的加载速度,而页面加载速度的关键就是页面资源的加载.本文将从浏览器浏览器页面资源加载过程展开分析,来引出页面关键请求路径的概念,并给出如何优化该关键请求路径的一些方法 ...
- android应用加载过程中的loading动画
应用加载过程中的loading动画: LoadingView .java /*** * loading 动画的实现 * @author * */ public class LoadingVi ...
- 配置项目启动的时候就加载 servlet
load-on-startup值为0 就是在项目启动的时候自动加载该servlet
最新文章
- R语言使用ggpubr包可视化分组条形图(grouped bar plot)、并添加误差条(error bar、误差条显示平均值+/-sd)、添加分组填充色、添加jitter、自定义分组抖动数据点形状
- 归并排序执行次数_归并排序过程、时间复杂度分析及改进
- stopstart按钮怎么用_烟雾报警器一直响吵人!怎么彻底给关掉?
- JVM详解之:汇编角度理解本地变量的生命周期
- Android官方开发文档Training系列课程中文版:添加ActionBar之ActionBar浮层效果
- 吉林建筑大学计算机科学技术,魏立明 - 吉林建筑大学 - 电气与计算机学院
- IP地址 0.0.0.0 是什么意思?
- 全网首发!超全SparseR-CNN实战教程
- 【2012 - 百度之星资格赛 - H:用户请求中的品牌】
- Python 中的闭包
- Python实战——为人脸照片添加口罩
- HTTP接口的请求参数类型有哪些
- 串口收 程序FPGA
- RocketMQ(10)——发送延时消息
- python中使用缩进来体现代码之间的逻辑关系_Python使用缩进来体现代码之间的逻辑关系....
- 3825. 逃离大森林
- 600道计算机二级python选择题在线真题题库
- 外贸:掌握这5个社交软件,让你不在为营销推广感到烦恼
- React+Redux技术栈核心要点解析(下篇)
- SAP 成本中心和内部订单浅析