插件的管理,加载机制

插件的管理加载主要涉及以下几个类:

  1. pluginEntry.java
  2. ConfigXmlParser.java
  3. CordovaPlugin.java
  4. PluginManager.java
  5. PluginResult.java

以下分别对该类做说明

pluginEntry.java

顾名思义插件条目 该类用来保存插件的服务名和该服务名对应的插件类
比如camera插件对应的服务名为'Camera',对应的类名名为 'org.apache.cordova.camera.CameraLauncher'
之后需要加载插件的时候可以通过插件类名来动态生成该插件实例

ConfigXmlParser.java

该文件的作用是用来解析config.xml,并初始化CordovaPreferences和pluginEntry

CordovaPlugin.java

插件核心类所有自定一的插件均需要继承自该类

PluginManager.java

顾名思义就是管理Cordova项目当中的所有插件,可以找到用来保存插件的如下变量
private final LinkedHashMap<String, CordovaPlugin> pluginMap = new LinkedHashMap<String, CordovaPlugin>();
private final LinkedHashMap<String, PluginEntry> entryMap = new LinkedHashMap<String, PluginEntry>();

以及执行对应插件的方发

    /*
    通过对应的service名来加载插件实例,并通过action名来执行插件实例的对应方法
    比如相机例子,最终调用相机插件通过该类的exec方法 首先根据前端传入的服务名'Camera'来获得对应插件实例
    在根据前端传入的action 'takePicture' 来执行实例的takePicture方法
    */
    public void exec(final String service, final String action, final String callbackId, final String rawArgs) {
        //根据插件的service名来获取对应的插件实例
        CordovaPlugin plugin = getPlugin(service);
        //如果插件没找到,则直接返回数据给前端,sendPluginResult方法实质是调用 nativeToJsMessageQueue.addPluginResult(cr, callbackId);
        //来向js发送数据
        if (plugin == null) {
            LOG.d(TAG, "exec() call to unknown plugin: " + service);
            PluginResult cr = new PluginResult(PluginResult.Status.CLASS_NOT_FOUND_EXCEPTION);
            app.sendPluginResult(cr, callbackId);
            return;
        }
        //前端每次执行exec动作原生总会用CallbackContext对象来保存当前动作的callbackId,根据该ID来找对应的成功,失败回调方法并执行
        CallbackContext callbackContext = new CallbackContext(callbackId, app);
        try {
            long pluginStartTime = System.currentTimeMillis();
            //执行对应插件的execute方法
            boolean wasValidAction = plugin.execute(action, rawArgs, callbackContext);
            long duration = System.currentTimeMillis() - pluginStartTime;

            if (duration > SLOW_EXEC_WARNING_THRESHOLD) {
                LOG.w(TAG, "THREAD WARNING: exec() call to " + service + "." + action + " blocked the main thread for " + duration + "ms. Plugin should use CordovaInterface.getThreadPool().");
            }
            if (!wasValidAction) {
                PluginResult cr = new PluginResult(PluginResult.Status.INVALID_ACTION);
                //sendPluginResult方法实质是调用 nativeToJsMessageQueue.addPluginResult(cr, callbackId);
                callbackContext.sendPluginResult(cr);
            }
        } catch (JSONException e) {
            PluginResult cr = new PluginResult(PluginResult.Status.JSON_EXCEPTION);
            callbackContext.sendPluginResult(cr);
        } catch (Exception e) {
            LOG.e(TAG, "Uncaught exception from plugin", e);
            callbackContext.error(e.getMessage());
        }
    }

PluginResult.java

顾名思义就用来保存插件的执行结果

插件的加载流程步骤

1.CordovaActivity.java中调用loadConfig方法来初始化PluginEntry

    @SuppressWarnings("deprecation")
    protected void loadConfig() {
        ConfigXmlParser parser = new ConfigXmlParser();
        parser.parse(this);//解析config.xml文件并读取首选项和插件
        preferences = parser.getPreferences();
        preferences.setPreferencesBundle(getIntent().getExtras());
        launchUrl = parser.getLaunchUrl();
        pluginEntries = parser.getPluginEntries();
        Config.parser = parser;
    }

2.CordovaActivity.java 调用init方法初始化webview(CordovaWebViewImpl.java实例)

    protected void init() {
        appView = makeWebView();
        createViews();
        if (!appView.isInitialized()) {
            //appView为CordovaWebViewImpl.java的一个实例
            appView.init(cordovaInterface, pluginEntries, preferences);
        }

        ....
    }
3.appView(CordovaWebViewImpl.java)调用init方法初始化PluginManager(见CordovaWebViewImpl.java init方法)

4.经过以上步骤相机插件实例就已经存在于PluginManager的对象当中,首先先读config.xml获取相机的类名,服务名
  并保存到pluginEntries数组中,之后再将pluginEntries丢给CordovaWebViewImpl实例,并在实例当中用pluginEntries
  初始化PluginManager,之后执行任何一个插件都通过PluginManager的来搜索对应插件并执行

results matching ""

    No results matching ""