您的位置:首页 > 移动开发

Android Browser App 源码分析(三)之UI篇第一讲

2017-01-03 17:24 489 查看
Android Native Browser的界面还是比较单一,比较少的。主要体现为:主界面(主要用于加载网页)、设置页面(用于设置浏览器中各个属性,比如是否启用JavaScript、是否保存密码等)、书签&历史记录页面(展示书签以及访问网页的历史记录)。

首先从代码层面分析下主界面的UI逻辑实现,看看到底是如何加载网页的。

(一)基础架构

Browser定义了UI接口来统管整个主界面的操作,以及对Activity生命周期发生变化的处理。

因Browser App同时也要兼容平板设备,所以,这里又抽象出一个抽象类BaseUi来实现手机与平板公共通用的部分,然后将差异性的方法通过派生类PhoneUi与XLargeUi来实现。

Browser主界面头部会有一个标题栏,主要用于输入网址、保存书签,因为平板与手机的尺寸是不同的,对应的头部Tab页导航展示也就不同了,所以Browser内部又声明了NavigationBarPhone、NavigationBarTablet类来进行处理,他们继承于NavigationBarBase类。

整个结构关系如下:





(二)主界面如何Load出来的

启动页:BrowserActivity::onCreate()

初始化Controller 对象

然后调用Controller start方法

然后调用CrashRecoveryHandler startRecovery方法

CrashRecoveryHandler实例的初始化调用在Controller构造函数中:

mCrashRecoveryHandler = CrashRecoveryHandler.initialize(this); //实例化CrashRecoveryHandler对象,CrashRecoveryHandler构造函数中同时又创建了foregroundHandler和backgroundHandler

mCrashRecoveryHandler.preloadCrashState();

//mBackgroundHandler.sendEmptyMessage(MSG_PRELOAD_STATE); 

调用loadCrashState,从STATE_FILE(browser_state.parcel)文件中读入到mRecoveryState中

调用mController.doStart(mRecoveryState, intent); 将mRecoveryState传递过去

然后对mRecoveryState中的lastActiveDate进行判断,如果最后一次浏览器的使用时间在24小时内,否则的话销毁所有剩余的隐身标签页。

调用mTabControl.canRestoreState来获取TabId

如果等于-1,执行CookieManager.getInstance().removeSessionCookie()

然后调用GoogleAccountLogin.startLoginIfNeeded进行登录

如果已经登录或者没有找到账号,直接执行runnable.run 方法

否则执行登录操作

onPreloginFinished 方法:

如果tabId等于-1(默认的情况下第一次进来为-1):

如果intent为null:调用openTabToHomePage方法,打开主页

如果intent不为null:获取urlData,如果为空:调用openTabToHomePage方法,打开主页

否则打开Tab,加载对应的urlData

调用openTabToHomePage:

openTab(mSettings.getHomePage(), false, true, false);

最终会调用这个openTab(String url, boolean incognito, boolean setActive,boolean useCurrent, Tab parent)方法:

通过createNewTab创建一个Tab对象

内部是通过TabControl.createNewTab来进行创建

createNewTab(boolean privateBrowsing)---> createNewTab(Bundle state, boolean privateBrowsing) ---->  createNewWebView实例化WebView对象---> mController.getWebViewFactory().createWebView(privateBrowsing)

----> BrowserWebViewFactory.createWebView 创建WebView

-----> instantiateWebView、initWebViewSettings

WebView创建完毕之后,开始实例化一个Tab对象,并添加到mTabs集合中:

Tab t = new Tab(mController, w, state);

mTabs.add(t);

调用Controller.onSetWebView ---> mUi.onSetWebView(tab, view);

----->BaseUi.onSetWebView

然后container = mActivity.getLayoutInflater().inflate(R.layout.tab, mContentView, false); 创建装载WebView的Tab容器

之后调用  t.putInBackground(); 先把标签放入后台

调用addTab()-->mUi.addTab 将tab传递到对应的UI中

这个方法PhoneUi没有重写,XLargeUi重写了。

然后调用 Controller.setActiveTab(tab) --->  mTabControl.setCurrentTab(tab)、mUi.setActiveTab(tab)

--->PhoneUi::setActiveTab

--->BaseUi::setActiveTab

--->attachTabToContentView(tab)

protected void attachTabToContentView(Tab tab) {
if ((tab == null) || (tab.getWebView() == null)) {
return;
}
View container = tab.getViewContainer();
WebView mainView  = tab.getWebView();
// Attach the WebView to the container and then attach the
// container to the content view.
FrameLayout wrapper =
(FrameLayout) container.findViewById(R.id.webview_wrapper);
ViewGroup parent = (ViewGroup) mainView.getParent();
if (parent != wrapper) {
if (parent != null) {
parent.removeView(mainView);
}
wrapper.addView(mainView);
}
parent = (ViewGroup) container.getParent();
if (parent != mContentView) {
if (parent != null) {
parent.removeView(container);
}
mContentView.addView(container, COVER_SCREEN_PARAMS);
}
mUiController.attachSubWindow(tab);
}


获取Tab的ViewContainer,获取container中的webview_wrapper控件,然后将tab对应的webView添加到其中,然后再将container添加到mContentView中

那mContentView是从哪里来的呢?

是通过实例化PhoneUi对象来的,在BaseUi构造函数中;
FrameLayout frameLayout = (FrameLayout) mActivity.getWindow()
.getDecorView().findViewById(android.R.id.content);
LayoutInflater.from(mActivity)
.inflate(R.layout.custom_screen, frameLayout);
mContentView = (FrameLayout) frameLayout.findViewById(R.id.main_content);


然后调用loadUrl来加载url

loadUrl(Tab tab, String url)-->loadUrl(Tab tab, String url, Map<String, String> headers)

if (tab != null) {
dismissSubWindow(tab);
tab.loadUrl(url, headers);
mUi.onProgressChanged(tab);
}


Tab.java:
public void loadUrl(String url, Map<String, String> headers) {
if (mMainView != null) {
mPageLoadProgress = INITIAL_PROGRESS;
mInPageLoad = true;
mCurrentState = new PageState(mContext, false, url, null);
mWebViewController.onPageStarted(this, mMainView, null);
mMainView.loadUrl(url, headers);
}
}


最终执行mMainView loadUrl方法加载url,显示对应url的网页。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android browser 源码