问题 在Android中混合使用cordova和本机活动


我希望我的大部分应用程序(列表项,存储,登录,关于屏幕等等)都在cordova中处理,因为在本机工作流程中这样做很痛苦。

但是我有一个特定的活动(我已经创建了)无法用cordova完成(至少不够好和足够快)。 我该如何创建这个应用程序?

  • 我应该创建一个仅加载这两个的cordova插件 活动?
  • 我应该通过cli生成cordova应用程序还是应该将cordova嵌入到一个活动中?

如果有更多的材料,我很乐意听到它。

提前致谢。


11695
2018-01-03 16:15


起源



答案:


这取决于您创建的活动。

如果您的主要活动是Cordova屏幕,并且它将全屏显示,并且Cordova部分上的某些操作将针对特定任务启动您的本机活动,那么您应该使用插件,使用intent启动您的活动当你完成它时,你关闭它然后回到Cordova活动,返回一个值或不返回值。

如果您想将Cordova视图与本机视图混合在一起,其中没有一个是全屏的,那么您应该在本机项目中嵌入Cordova。

如果您的活动将成为您的主要活动,那么嵌入Cordova是您唯一的选择。

正如你要求的例子,你不认为真正的插件不是一个很好的例子,我会简化 插件创建指南 

插件需要一个如下所示的plugin.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
        id="your-plugin-id" version="1.0.0">
    <name>pluginName</name>
    <description>description of the plugin</description>
    <license>License of the plugin</license>
    <js-module src="www/pluginName.js" name="pluginName">
        <clobbers target="pluginName" />
    </js-module>
    <platform name="android">
        <config-file target="res/xml/config.xml" parent="/*">
            <feature name="PluginName" >
                <param name="android-package" value="your.plugin.package.pluginName"/>
            </feature>
        </config-file>

        <source-file src="src/android/PluginName.java" target-dir="your/plugin/package/PluginName" />
    </platform>
</plugin>

通过查看它,你可以看到你还需要一个带有pluginName.js文件的www文件夹,以及一个带有pluginName.java文件的src / android文件夹。

pluginName.js应该是这样的:

function showNativeView() {
    cordova.exec(successCallback, errorCallback, "PluginName", "showNativeView", [arguments]);
}

第一个参数是插件完成执行时调用的successCallback函数。 第二个参数是如果插件有任何问题则调用的errorCallback函数 第三个参数是您将调用的java类的名称,它必须与plugin.xml上的类匹配 第四个参数是在java类中调用的动作 第五个是数组或参数,如果你想发送任何数组。 要执行它,只需按一下按钮即可调用showNativeView()。 提醒一下,这是过度简化的,正确的做法应该是为插件创建命名空间并为其添加不同的功能,但我想保持简单。

最后,PluginName.java应该是这样的:

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if ("showNativeView".equals(action)) {
            Intent yourIntent = new Intent(this.cordova.getActivity().getBaseContext(), YourActivityToLaunch.class);
cordova.getActivity().startActivity(yourIntent);
            callbackContext.success();
            return true;
        }
        return false;  // Returning false results in a "MethodNotFound" error.
    }

这会启动一个简单的意图,如果您的活动返回了必须使用的内容,则不返回任何内容

this.cordova.startActivityForResult(this, yourIntent, REQUEST_CODE);

并添加

@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    String result = intent.getStringExtra("WHATEVER_THE_INTENT_RETURNS"),
    this.callbackContext.success(result);
}

您在此处调用成功,而不是在启动intent后立即执行此操作,并返回活动返回的值。您还应该检查REQUEST_CODE以匹配您用于启动意图的活动,活动的结果等。


9
2017-12-15 15:16



你能展示一些代码示例吗? - funerr
相机插件发布了一个意图 github.com/apache/cordova-plugin-camera,inAppBrowser插件也是如此 github.com/apache/cordova-plugin-inappbrowser,条形码扫描仪插件也 github.com/phonegap/phonegap-plugin-barcodescanner。关于嵌入Cordova webview,我没有示例,Cordova网站上的指南非常过时。 - jcesarmobile
我的意思是添加如下代码:[cordova按钮打开本机意图] - > [本机代码] +文件的应用程序结构。有一天,加上链接可以被404。 - funerr
其中两个链接是官方插件,如果它们消失是因为Cordova已经死了,问题也没有意义,但无论如何我会添加简单的例子。 - jcesarmobile
谢啦! @jcesarmobile - funerr


答案:


这取决于您创建的活动。

如果您的主要活动是Cordova屏幕,并且它将全屏显示,并且Cordova部分上的某些操作将针对特定任务启动您的本机活动,那么您应该使用插件,使用intent启动您的活动当你完成它时,你关闭它然后回到Cordova活动,返回一个值或不返回值。

如果您想将Cordova视图与本机视图混合在一起,其中没有一个是全屏的,那么您应该在本机项目中嵌入Cordova。

如果您的活动将成为您的主要活动,那么嵌入Cordova是您唯一的选择。

正如你要求的例子,你不认为真正的插件不是一个很好的例子,我会简化 插件创建指南 

插件需要一个如下所示的plugin.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
        id="your-plugin-id" version="1.0.0">
    <name>pluginName</name>
    <description>description of the plugin</description>
    <license>License of the plugin</license>
    <js-module src="www/pluginName.js" name="pluginName">
        <clobbers target="pluginName" />
    </js-module>
    <platform name="android">
        <config-file target="res/xml/config.xml" parent="/*">
            <feature name="PluginName" >
                <param name="android-package" value="your.plugin.package.pluginName"/>
            </feature>
        </config-file>

        <source-file src="src/android/PluginName.java" target-dir="your/plugin/package/PluginName" />
    </platform>
</plugin>

通过查看它,你可以看到你还需要一个带有pluginName.js文件的www文件夹,以及一个带有pluginName.java文件的src / android文件夹。

pluginName.js应该是这样的:

function showNativeView() {
    cordova.exec(successCallback, errorCallback, "PluginName", "showNativeView", [arguments]);
}

第一个参数是插件完成执行时调用的successCallback函数。 第二个参数是如果插件有任何问题则调用的errorCallback函数 第三个参数是您将调用的java类的名称,它必须与plugin.xml上的类匹配 第四个参数是在java类中调用的动作 第五个是数组或参数,如果你想发送任何数组。 要执行它,只需按一下按钮即可调用showNativeView()。 提醒一下,这是过度简化的,正确的做法应该是为插件创建命名空间并为其添加不同的功能,但我想保持简单。

最后,PluginName.java应该是这样的:

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if ("showNativeView".equals(action)) {
            Intent yourIntent = new Intent(this.cordova.getActivity().getBaseContext(), YourActivityToLaunch.class);
cordova.getActivity().startActivity(yourIntent);
            callbackContext.success();
            return true;
        }
        return false;  // Returning false results in a "MethodNotFound" error.
    }

这会启动一个简单的意图,如果您的活动返回了必须使用的内容,则不返回任何内容

this.cordova.startActivityForResult(this, yourIntent, REQUEST_CODE);

并添加

@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    String result = intent.getStringExtra("WHATEVER_THE_INTENT_RETURNS"),
    this.callbackContext.success(result);
}

您在此处调用成功,而不是在启动intent后立即执行此操作,并返回活动返回的值。您还应该检查REQUEST_CODE以匹配您用于启动意图的活动,活动的结果等。


9
2017-12-15 15:16



你能展示一些代码示例吗? - funerr
相机插件发布了一个意图 github.com/apache/cordova-plugin-camera,inAppBrowser插件也是如此 github.com/apache/cordova-plugin-inappbrowser,条形码扫描仪插件也 github.com/phonegap/phonegap-plugin-barcodescanner。关于嵌入Cordova webview,我没有示例,Cordova网站上的指南非常过时。 - jcesarmobile
我的意思是添加如下代码:[cordova按钮打开本机意图] - > [本机代码] +文件的应用程序结构。有一天,加上链接可以被404。 - funerr
其中两个链接是官方插件,如果它们消失是因为Cordova已经死了,问题也没有意义,但无论如何我会添加简单的例子。 - jcesarmobile
谢啦! @jcesarmobile - funerr