访问 Phonegap 插件中 UI 线程上运行的对话框

发布于 2024-12-29 06:18:49 字数 4114 浏览 3 评论 0原文

我是 Android 开发新手,我需要实现类似于 ChildBrowser插件

虽然我已经成功实现了此对话框的大部分功能,包括某些对话框操作上的 JS 回调事件,但我无法实现在显示时将数据从 JS 发送回对话框。

场景如下:当对话框的 Spinner 更改时,JS 回调被调用,JS 代码执行一些处理(访问 sqlStorage 数据等),然后我需要更新对话框的一些视图。我当前的代码(没有不相关的东西):

CustomDialogPlugin.java:

public class CustomDialogPlugin extends Plugin {
    @Override
    public PluginResult execute(String action, JSONArray args, String callbackId) {
        PluginResult.Status status = PluginResult.Status.OK;
        String result = "";

        try {
            if (action.equals("show")) {
                result = this.showDialog(args.optJSONObject(0), callbackId);
                // ...
            } else if (action.equals("update")) {
                this.updateData(args.optJSONObject(0));
            }
        } catch(JSONException e) {
            // ...
        }
    }

    // Show the dialog
    public String showDialog(JSONObject options, final String callbackId) {
        if (options != null) {
            // Handle options
        }

        // Create the child dialog in new thread
        Runnable runnable = new Runnable() {

            public void run() {
                mDialog = new Dialog(ctx);
                // Dialog layouts, views and listeners setup
                // ...
                mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
                    @Override
                    public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
                        // ...
                        // Prepare JSON data to send and call a callback
                        sendUpdate(CHANGED_EVENT, obj, true);
                    }

                    @Override
                    public void onNothingSelected(AdapterView adapter) {
                        // ...
                    }
                });
                // ...
                mDialog.show();
            }
        };
        this.ctx.runOnUiThread(runnable);
        return "";
    }

    // Create a new plugin result and send it back to JavaScript
    private void sendUpdate(int eventType, JSONObject obj, boolean keepCallback) {
        if (this.savedCallbackId != null) {
            // ...
            PluginResult result = new PluginResult(PluginResult.Status.OK, obj);
            Result.setKeepCallback(keepCallback);
            this.success(result, this.savedCallbackId);
        }
    }

    // Parse data received from JS and upate dialog
    protected String updateData(JSONObject data) {
        // Here I need to update some views of mDialog
        // Can't access them from here
    }
}

customdialog.js:

var CustomDialog = function() {};
CustomDialog.CHANGED_EVENT = 1;

CustomDialog.prototype.show = function(data) {
    return PhoneGap.exec(this._onEvent, this._onError, 'CustomDialogPlugin', 'show', [data]);
};

CustomDialog.prototype.update = function(data) {
    return PhoneGap.exec(this._onEvent, this._onError, 'CustomDialogPlugin', 'update', [data]);
};

CustomDialog.prototype._onEvent = function(data) {
    if (data.type == CustomDialog.CHANGED_EVENT && typeof window.plugins.CustomDialog.onChange === "function") {
        window.plugins.CustomDialog.onChange(data);
    }
    // ...
};
CustomDialog.prototype._onError = function(data) {
    // ...
};

PhoneGap.addConstructor(function() {
    PhoneGap.addPlugin('customDialog', new CustomDialog());
});

test.html:

// ...
window.plugins.customDialog.onChange = function(data) {
    // ...
    window.plugins.customDialog.update(some_other_data);
}

我尝试创建在 Runnable 中创建一个 Handler,并调用它来处理从 updateData 发送的消息,但显然我做错了什么。

也许我把事情过于复杂化了,有一种更简单的方法可以通过 JS 回调完成数据更新吗?

先感谢您。

I'm new to Android development, I needed to implement custom dialog plugin similar to the one in the ChildBrowser plugin.

While I have managed to implement most of the functionality for this dialog, including JS callback events on certain dialog actions, I was unable to implement sending data from JS back to the dialog while it's shown.

Scenario is the following: when the dialog's Spinner is changed, JS callback is being called, JS code performs some processing (access sqlStorage data, etc.) and afterwards I need to update some views of the dialog. My current code (without non-relevant things):

CustomDialogPlugin.java:

public class CustomDialogPlugin extends Plugin {
    @Override
    public PluginResult execute(String action, JSONArray args, String callbackId) {
        PluginResult.Status status = PluginResult.Status.OK;
        String result = "";

        try {
            if (action.equals("show")) {
                result = this.showDialog(args.optJSONObject(0), callbackId);
                // ...
            } else if (action.equals("update")) {
                this.updateData(args.optJSONObject(0));
            }
        } catch(JSONException e) {
            // ...
        }
    }

    // Show the dialog
    public String showDialog(JSONObject options, final String callbackId) {
        if (options != null) {
            // Handle options
        }

        // Create the child dialog in new thread
        Runnable runnable = new Runnable() {

            public void run() {
                mDialog = new Dialog(ctx);
                // Dialog layouts, views and listeners setup
                // ...
                mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
                    @Override
                    public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
                        // ...
                        // Prepare JSON data to send and call a callback
                        sendUpdate(CHANGED_EVENT, obj, true);
                    }

                    @Override
                    public void onNothingSelected(AdapterView adapter) {
                        // ...
                    }
                });
                // ...
                mDialog.show();
            }
        };
        this.ctx.runOnUiThread(runnable);
        return "";
    }

    // Create a new plugin result and send it back to JavaScript
    private void sendUpdate(int eventType, JSONObject obj, boolean keepCallback) {
        if (this.savedCallbackId != null) {
            // ...
            PluginResult result = new PluginResult(PluginResult.Status.OK, obj);
            Result.setKeepCallback(keepCallback);
            this.success(result, this.savedCallbackId);
        }
    }

    // Parse data received from JS and upate dialog
    protected String updateData(JSONObject data) {
        // Here I need to update some views of mDialog
        // Can't access them from here
    }
}

customdialog.js:

var CustomDialog = function() {};
CustomDialog.CHANGED_EVENT = 1;

CustomDialog.prototype.show = function(data) {
    return PhoneGap.exec(this._onEvent, this._onError, 'CustomDialogPlugin', 'show', [data]);
};

CustomDialog.prototype.update = function(data) {
    return PhoneGap.exec(this._onEvent, this._onError, 'CustomDialogPlugin', 'update', [data]);
};

CustomDialog.prototype._onEvent = function(data) {
    if (data.type == CustomDialog.CHANGED_EVENT && typeof window.plugins.CustomDialog.onChange === "function") {
        window.plugins.CustomDialog.onChange(data);
    }
    // ...
};
CustomDialog.prototype._onError = function(data) {
    // ...
};

PhoneGap.addConstructor(function() {
    PhoneGap.addPlugin('customDialog', new CustomDialog());
});

test.html:

// ...
window.plugins.customDialog.onChange = function(data) {
    // ...
    window.plugins.customDialog.update(some_other_data);
}

I've tried to create a Handler inside Runnable, and call it to handle message sent from updateData, but apparently I'm doing something wrong.

Maybe I'm over-complicating things and there is an easier way to accomplish data update from JS callback?

Thank you in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

似梦非梦 2025-01-05 06:18:49

好的,这是一个解决方案(使用 Post)最终对我有用(函数/返回值的参数与我原来的问题中的不同,但这仍然是我要问的函数):

protected void updateData(String data) {
    mMyEdit.post(
        new Runnable() {
            public void run() {
                mMyEdit.setText(data);
            }
        }
);
}

OK, here is a solution (using Post) that finally worked for me (parameter of the function/return value are not the same as in my original question, but this is still the function I was asking about):

protected void updateData(String data) {
    mMyEdit.post(
        new Runnable() {
            public void run() {
                mMyEdit.setText(data);
            }
        }
);
}
残花月 2025-01-05 06:18:49

Android ChildBrowser 插件的代码可能会对您有所帮助,因为它还会在 PhoneGap 插件中打开一个对话框。

https://github.com/phonegap/phonegap-plugins/blob/master/Android/ChildBrowser/src/com/phonegap/plugins/childBrowser/ChildBrowser.java

取决于你是什么尝试更新如果您在主插件类中引用了要更新的视图,那么应该没问题。

The code for the Android ChildBrowser plugin may help you as it also opens up a dialog in a PhoneGap Plugin.

https://github.com/phonegap/phonegap-plugins/blob/master/Android/ChildBrowser/src/com/phonegap/plugins/childBrowser/ChildBrowser.java

Depending on what you are trying to update if you have a reference to the view you want to update in the main plugin class you should be okay.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文