前面把插件在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="dev@cordova.apache.org" 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
public void loadUrl(String url) {
if (appView == null) {
init(); //第一次肯定需要初始化 跳转到代码段2
}
// If keepRunning
this.keepRunning = preferences.getBoolean("KeepRunning", true);
appView.loadUrlIntoView(url, true);
}
代码段2:
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部分,我们自己构建一套属于我们自己的架构应该也是没有问题了
下面就根据我们自己的需求设计我们自己的架构吧。