您好,登錄后才能下訂單哦!
當我們在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文件:
<merge xmlns: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.CustomScreenLinearLayout android: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方法。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。