Cordova原始碼深入分析-第四講
阿新 • • 發佈:2019-01-10
前面把外掛在js端的初始化,與js->Native->js端的通訊都介紹了一下
本章介紹一下,在native端的外掛初始化流程
在介紹所有的之前,我想先上一段程式碼(外掛配置):
<?xml version='1.0' encoding='utf-8'?> <widget id="io.cordova.hellocordova" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"> <feature name="Whitelist"> <param name="android-package" value="org.apache.cordova.whitelist.WhitelistPlugin" /> <param name="onload" value="true" /> </feature> <feature name="Camera"> <param name="android-package" value="org.apache.cordova.camera.CameraLauncher" /> </feature> <feature name="SMS"> <param name="android-package" value="com.rjfun.cordova.sms.SMSPlugin" /> </feature> <feature name="Notification"> <param name="android-package" value="org.apache.cordova.dialogs.Notification" /> </feature> <name>HelloCordova</name> <description> A sample Apache Cordova application that responds to the deviceready event. </description> <author email="
[email protected]" href="http://cordova.io"> Apache Cordova Team </author> <content src="index.html" /> <access origin="*" /> <allow-intent href="http://*/*" /> <allow-intent href="https://*/*" /> <allow-intent href="tel:*" /> <allow-intent href="sms:*" /> <allow-intent href="mailto:*" /> <allow-intent href="geo:*" /> <allow-intent href="market:*" /> <preference name="loglevel" value="DEBUG" /> </widget>
還是從Activity的onCrete開始分析,首先呼叫的是CordovaActivity.java的loadUrl
程式碼段:1
程式碼段2:public void loadUrl(String url) { if (appView == null) { init(); //第一次肯定需要初始化 跳轉到程式碼段2 } // If keepRunning this.keepRunning = preferences.getBoolean("KeepRunning", true); appView.loadUrlIntoView(url, true); }
protected void init() {
appView = makeWebView();//構建整個架構框架,程式碼段3
createViews(); //建立view的地方,沒有太多邏輯,不關注了
if (!appView.isInitialized()) {
appView.init(cordovaInterface, pluginEntries, preferences);//這裡是重點,程式碼段4
}
cordovaInterface.onCordovaInit(appView.getPluginManager());
// Wire the hardware volume controls to control media if desired.
String volumePref = preferences.getString("DefaultVolumeStream", "");
if ("media".equals(volumePref.toLowerCase(Locale.ENGLISH))) {
setVolumeControlStream(AudioManager.STREAM_MUSIC);
}
}
程式碼段3:
protected CordovaWebView makeWebView() {
return new CordovaWebViewImpl(makeWebViewEngine());
}
這裡涉及到兩個類,CordovaWebViewImpl 和 SystemWebViewEngine
engine是整個架構和核心的幹活的類,所有WebView的設定和操作都在這裡實現
Impl則是整個架構的核心管理模組,負責協調各個功能之間的互動,包括訊息中心,外掛管理中心等等的初始化和呼叫
程式碼段4:
入參,都是在CordovaActivity的onCreate中早就初始化好了,這裡只是傳入的,外掛的所有資訊都記錄在
res/xml/config.xml中,這個邏輯比較簡單,就一筆帶過了。
public void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences) {
if (this.cordova != null) {
throw new IllegalStateException();
}
this.cordova = cordova;
this.preferences = preferences;//配置中的preference引數
pluginManager = new PluginManager(this, this.cordova, pluginEntries);//所有的外掛資訊都在這裡管理
resourceApi = new CordovaResourceApi(engine.getView().getContext(), pluginManager);//可以理解為工具類(資源讀取)
nativeToJsMessageQueue = new NativeToJsMessageQueue();//之前介紹過的訊息佇列,負責native給js的方法呼叫
nativeToJsMessageQueue.addBridgeMode(new NativeToJsMessageQueue.NoOpBridgeMode());//封裝成js的方法,
nativeToJsMessageQueue.addBridgeMode(new NativeToJsMessageQueue.LoadUrlBridgeMode(engine, cordova));
if (preferences.getBoolean("DisallowOverscroll", false)) {
engine.getView().setOverScrollMode(View.OVER_SCROLL_NEVER);//滑動是否出現弧形光環
}
engine.init(this, cordova, engineClient, resourceApi, pluginManager, nativeToJsMessageQueue);//將所有資訊傳給Engine
// This isn't enforced by the compiler, so assert here.
assert engine.getView() instanceof CordovaWebViewEngine.EngineView;
pluginManager.addService(CoreAndroid.PLUGIN_NAME, "org.apache.cordova.CoreAndroid");//增加一個外掛(這屬於基礎外掛)
pluginManager.init(); //初始化 程式碼段5
}
程式碼段5:
public void init() {
LOG.d(TAG, "init()");
isInitialized = true;
this.onPause(false);//停止
this.onDestroy();//之前載入的外掛先呼叫onDestroy
pluginMap.clear();
this.startupPlugins();//這裡實際上就是將外掛的類物件加入到pluginMap中(LinkedHashMap<String, CordovaPlugin> pluginMap)
}
這裡在初始化的時候,有兩點需要提一下,外掛分為onLoad外掛和其他外掛,onLoad外掛是啟動時就直接載入的,
其他外掛只有在呼叫的時候,再去初始化後加載。
我們之前的程式碼邏輯呼叫過exec方法,其實就是到這裡的是,再去提取外掛,然後執行固定的程式碼。
到目前位置,應該是所有有疑問的點都已經分析過了,出去cli部分,我們自己構建一套屬於我們自己的架構應該也是沒有問題了
下面就根據我們自己的需求設計我們自己的架構吧。