【问题标题】:Android Cordova Plugin Development - Errors in JS InterfaceAndroid Cordova 插件开发 - JS 接口中的错误
【发布时间】:2017-08-01 19:02:51
【问题描述】:

我正在尝试为 Android 平台开发一个 Cordova 插件,诚然这是我的第一个插件,所以我的错误可能是基本的,但对于我的生活,我无法弄清楚为什么我的 cordova 插件会失败'不工作。我不断收到如下参考错误:

"Uncaught ReferenceError: require is not defined", source: file:///android_asset/www/js/pdfRenderer.js (3)

"Uncaught ReferenceError: initialize is not defined", source: file:///android_asset/www/index.html (10)

还有这个 TypeError "Uncaught TypeError: Cannot read property 'display' of undefined", source: file:///android_asset/www/js/index.js (37)

这是我的插件 Java 代码:

package com.dev.plugin.PdfRendererService;

import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.graphics.pdf.PdfRenderer;
import android.graphics.pdf.PdfRenderer.Page;

/**
 * This class handles a pdf file called from JavaScript and converts a 
selected page (default is first) to a byte array representing a bitmap.
 */
public class PdfRendererService extends CordovaPlugin {

private ParcelFileDescriptor fileDescriptor = null;
private PdfRenderer renderer = null;
private Page currentPage = null;

private int mWidth = 400, mHeight = 600;
private String mRenderMode = "display";

@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView){        
    super.initialize(cordova, webView);
}

@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
    this.validatePermissions();

    boolean isPageOpen = false;
    switch(action){
        case "open":
            return executeOpen(args, callbackContext);
        case "renderPage":
            return executeRenderPage(args, callbackContext);
        case "pageCount":
            callbackContext.success(this.getPageCount());
            return true;
        case "close":
            this.closeRenderer();
            callbackContext.success();
            return true;
    }
    return false;
}

private boolean executeOpen(JSONArray args, CallbackContext callbackContext){
    //TODO - Implement this method
    return true;
}

private boolean executeRenderPage(JSONArray args, CallbackContext callbackContext){
    //TODO - Implement this method
    return true;
}

private int getPageCount() {
    if(renderer == null)
        return 0;

    return renderer.getPageCount();
}

private void initializeWriteFileDescriptor(String filePath, CallbackContext callbackContext){
    //TODO - Implement this method
}

private void initializeRenderer(String filePath, CallbackContext callbackContext){
    renderer = null;

    initializeWriteFileDescriptor(filePath, callbackContext);

    if(fileDescriptor == null) {
        callbackContext.error("An error has occurred while loading the requested file.");
        return;
    }

    renderer = new PdfRenderer(fileDescriptor);
}

private void closeRenderer() {
    if(renderer == null) {
        return;
    }

    renderer.close();
}

private boolean openPage(int index, CallbackContext callbackContext){
    //TODO - Implement this method
    return true;
}

private void sendBitmapAsBytes(int index, Bitmap bitmap, CallbackContext callbackContext){
    //TODO - Implement this method
}

private static byte[] toByteArray(Bitmap bitmap){
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPG, 100, stream);

    return stream.toByteArray();
}

private static Bitmap getBitmap(int width, int height){
    return Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
}

private static ParcelFileDescriptor getWriteFileDescriptor(String filePath){
    return ParcelFileDescriptor(
            new File(filePath),
            ParcelFileDescriptor.MODE_TRUNCATE |
            ParcelFileDescriptor.MODE_CREATE   |
            ParcelFileDescriptor.MODE_WRITE_ONLY
    );
}
}

我的 Javascript 插件界面 (pdfRenderer.js)

'use strict';

var cordova = require('cordova');

var PLUGIN_NAME = "PdfRendererService";

var SERVICE_OPEN = "open";
var SERVICE_CLOSE = "close";
var SERVICE_PAGE_COUNT = "pageCount";
var SERVICE_RENDER_PAGE = "renderPage";

var RENDER_MODE_DISPLAY = "display";
var RENDER_MODE_PRINT = "print";

var PdfRendererPlugin = {
display: function(filePath, callback){
    cordova.exec(callback, function(err){
        console.log(err);
    }, PLUGIN_NAME, SERVICE_OPEN, [filePath, RENDER_MODE_DISPLAY]);
},

renderPage: function(pageNo, callback){
    cordova.exec(callback, function(err){
        console.log(err);
    }, PLUGIN_NAME, SERVICE_RENDER_PAGE, [pageNo]);
},

close: function(callback){
    cordova.exec(callback, function(err){
        console.log(err);
    }, PLUGIN_NAME, SERVICE_CLOSE, []);
},

getPageCount: function(callback){
    cordova.exec(callback, function(err){
        console.log(err);
    }, PLUGIN_NAME, SERVICE_PAGE_COUNT, []);
}
};

module.exports = PdfRendererPlugin;

index.js

var testFilePath = 'assets/software-development.pdf';

var app = {
// Application Constructor
initialize: function() {
    document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
},

// deviceready Event Handler
//
// Bind any cordova events here. Common events are:
// 'pause', 'resume', etc.
onDeviceReady: function() {
    this.display();
},

display: function(){
    PdfRendererPlugin.display(testFilePath, function(data){
    console.log('Bitmap Bytes');
        console.log(data);
    });
}
};

app.initialize();

index.html

<!DOCTYPE html>
<html>
<head>
    <title>Cordova PDF Generator Plugin Test</title>

    <meta name="viewport" content="user-scalable=no, initial-scale=1,
          maximum-scale=1, minimum-scale=1, width=device-width,
          height=device-height" />
</head>
<body onload="initialize()">
    <div class="app">
        <h1>Cordova PDF Generation Plugin Test</h1>
    </div>

    <script type="text/javascript" src="cordova.js"></script>
    <script type="text/javascript" src="js/pdfRenderer.js"></script>
    <script type="text/javascript" src="js/index.js"></script>
</body>
</html>

插件.xml

<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
    id="cordova-plugin-pdf-renderer" version="0.2.3">
<name>PdfRenderer</name>
<description>Cordova PDF Renderer Plugin</description>
<license>MIT</license>
<keywords>cordova,pdf,renderer</keywords>

<platform name="android">
    <js-module src="www/js/pdfRenderer.js" name="PdfRendererPlugin">
        <runs/>

        <clobbers target="PdfRendererPlugin" />
    </js-module>

    <config-file target="config.xml" parent="/*">
        <feature name="PdfRendererPlugin">
            <param name="android-package" value="com.dev.plugin.PdfRendererService"/>
            <param name="onload" value="true" />
        </feature>
    </config-file>

    <source-file src="src/android/PdfRendererService.java" target-dir="src/com/dev/plugin/" />
</platform>
</plugin>

谁能帮我弄清楚为什么会出现这些错误?

【问题讨论】:

    标签: javascript android node.js cordova cordova-plugins


    【解决方案1】:

    首先,您不能直接要求 Cordova 模块。 发生的情况是,当您将插件安装到 Android 平台时,Cordova CLI 会将您的 JS 插件组件包装在一个函数中:

    cordova.define("your.plugin.namespace", function(require, exports, module) {
    // Your plugin code
    });
    

    因此,在您的插件代码中,您可以假设cordova 已定义为全局变量,并且requireexportsmodule

    所以从你的pdfRenderer.js 中删除var cordova = require('cordova'); 行。

    您还应该从正文标记中删除onload 处理程序:&lt;body onload="initialize()"&gt;。 这不是必需的,因为 deviceready 事件正在(并且应该)用于启动应用程序初始化,并且您已经在 app.js 中拥有它

    这是我可以看到的两个明显错误,因此请尝试进行这些更改,看看会发生什么。

    【讨论】:

    • 谢谢!这是一个好的开始。这是我现在的错误:"Uncaught ReferenceError: module is not defined", source: file:///android_asset/www/js/pdfRenderer.js (81)"Class not found", source: file:///android_asset/www/js/pdfRenderer.js (16)
    • "Class not found", source: file:///android_asset/www/js/pdfRenderer.js (16) 这是因为您将插件命名为&lt;feature name="PdfRendererPlugin"&gt;,但您将其称为PLUGIN_NAME = "PdfRendererService";。使用相同名称命名插件的所有组件以避免此类问题是最简单的。
    • 由于您的建议,我似乎取得了更大的进步,并删除了 JS 接口的错误回调中的任何 console.log 调用。我不再收到这些错误,但现在当我尝试调用插件函数时,我收到以下错误:D/PluginManager: exec() call to unknown plugin: PdfRendererPlugin 这是来自 android 端,所以看起来 JS 接口正在工作。如果我的问题还没有答案,也许我应该关闭这个帖子并打开一个新帖子?
    • 我建议将当前 PdfRendererService 的所有内容重命名为 PdfRendererPlugin,以便在 JS-Java 接口之间保持一致性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多