Android 浏览器的研究(四)--- Apk的启动和主页的加载过程
當(dāng)我們?cè)?/span>Launcher中點(diǎn)擊瀏覽器的圖標(biāo)時(shí),瀏覽器的窗口會(huì)打開(kāi)并顯示主頁(yè)(HomePage)。這里我們對(duì)這一場(chǎng)景進(jìn)行分析,研究瀏覽器如何啟動(dòng),取得缺省主頁(yè)并將它布局和顯示的。
根據(jù)前邊對(duì)WebView 類(lèi)的學(xué)習(xí),大概可以預(yù)期我們?cè)谥?/span>Activity的onCreate方法里從設(shè)置里面取得缺省主頁(yè)的配置,創(chuàng)建一個(gè)WebView類(lèi),并使用setContentView將它添加到主窗口中。下面我們從瀏覽器的代碼看看它是如何實(shí)現(xiàn)的。
首先,研究AndroidManifest文件,從<application>標(biāo)簽的內(nèi)容看到該Apk實(shí)現(xiàn)了自己的Applicaton 類(lèi)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的啟動(dòng),首先是ApplicationBrowser類(lèi)的onCreate方法,主要工作:
? ?// create CookieSyncManager with current Context
? ?CookieSyncManager.createInstance(this);
? ?BrowserSettings.initialize(getApplicationContext());
? ?Preloader.initialize(getApplicationContext());
這里涉及到三個(gè)工作:Cookie同步管理,瀏覽器設(shè)置和預(yù)加載。
然后是Activity的onCreate方法,與我們的研究相關(guān)的代碼:
@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的創(chuàng)建,PhoneUi的創(chuàng)建和Controller的start。
Controller的構(gòu)造方法主要涉及到以下幾個(gè)相關(guān)類(lèi):
BrowserSettings
TabControl
CrashRecoveryHandler
UrlHandler
BrowserWebViewFactory
IntentHandler
PageDialogHandler
BookMarks的ContentObserver
NetworkStateHandler
SystemAllowGeolocationOrigins
IconDataBase
PhoneUi的構(gòu)造:
? ?BaseUi的構(gòu)造:
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>
可以看出這個(gè)是瀏覽器主界面的布局,瀏覽器的布局已經(jīng)準(zhǔn)備好,后面我們創(chuàng)建的WebView應(yīng)該是添加到main_content里面。
Controller 的start 方法執(zhí)行了CrashRecoveryHandler的startRecovery().
CrashRecoveryHandler相關(guān)操作:
首先是initialize(),創(chuàng)建了CrashRecoveryHandler實(shí)例,CrashRecoveryHandler實(shí)例構(gòu)造了foregroundHandler和backgroundHandler。
CrashRecoveryHandler的preloadCrashState方法,在backgroundHandler的處理中執(zhí)行loadCrashState(),該方法將CrashState從STATE_FILE讀入到mRecoveryState中。
CrashRecoveryHandler的startRecovery方法,調(diào)用Controller的doStart()。
Controller的doStart方法調(diào)用onPreloginFinished().
currentTabId is -1, thenopenTabToHomePage().
openTabToHomePage
createNewTabthen loadUrl.
createNewTab的實(shí)現(xiàn):
TabControl::createNewTab
createNewWebView:
new BrowserWebView;該類(lèi)主要用來(lái)管理WebView滾動(dòng)條事件。
initWebViewSettings;
setActiveTab
TabControl::setCurrentTab
PhoneUi::setActiveTab
attachTabToContentView
至此,我們看完Apk啟動(dòng)并加載HomePage的過(guò)程,簡(jiǎn)單總結(jié)如下:
1.瀏覽器實(shí)現(xiàn)了自己的Application類(lèi)(Browser),在其onCreate方法中進(jìn)行了一些初始化工作(Cookie同步管理,瀏覽器設(shè)置和預(yù)加載);
2.瀏覽器的主Activity是BrowserActivity,在其onCreate方法中構(gòu)建了Controller和PhoneUi,并調(diào)用Controller::start方法啟動(dòng)Controller;
a)Controller在其構(gòu)造方法中實(shí)例化和初始化一些協(xié)助對(duì)象,其中一個(gè)重要的類(lèi)是CrashRecoveryHandler;
b)PhoneUi的構(gòu)造方法加載custom_screen布局文件,并將它作為Activity窗口的ContentView.
c)Controller::start方法執(zhí)行了CrashRecoveryHandler的startRecovery(),該方法又調(diào)用Controller的doStart()方法
i.Controller的doStart方法調(diào)用onPreloginFinished(),該方法執(zhí)行openTabToHomePage,打開(kāi)瀏覽器主頁(yè)。具體將WebView加到ContentView的方法是BaseUi的attachTabToContentView方法。
轉(zhuǎn)載于:https://blog.51cto.com/sunhongbo/1357127
總結(jié)
以上是生活随笔為你收集整理的Android 浏览器的研究(四)--- Apk的启动和主页的加载过程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。