访问 Phonegap 插件中 UI 线程上运行的对话框
我是 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好的,这是一个解决方案(使用 Post)最终对我有用(函数/返回值的参数与我原来的问题中的不同,但这仍然是我要问的函数):
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):
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.