Android Phonegap: powiadom javascript, gdy AsyncTask jest zakończona
W mojej aplikacji, gdy użytkownik kliknie przycisk w webview, zostanie wywołana wtyczka phonegap, która uruchomi asynctask, aby pobrać plik z Internetu. Teraz chcę wysłać sygnał z powrotem do części javascript po zakończeniu asynctask. Ale nie wiem, jak to zrobić, bo mój plugin już wysłać coś z powrotem przed AsyncTask jest zakończona. Czy ktoś wie, jak mogę powiadomić moją część javascript bez wtyczki w Phonegap?
3 answers
Zadałem to pytanie również w Phonegap Google Group, oto odpowiedź Simon Mac Donald. U mnie działa idealnie:
Możesz poradzić sobie z tą sytuacją, używając API wtyczki dość łatwo. Informatyka jest zaimplementowany w podstawowych elementach API połączenia i baterii. Co Ty trzeba to zrobić:
1) w metodzie execute () wtyczki Zapisz otrzymany identyfikator callbackId.
2) zwraca wynik wtyczki NO_RESULT i ustawia keep callback id na true.
PluginResult pluginResult = new PluginResult(PluginResult.Status.NO_RESULT);
pluginResult.setKeepCallback(true);
return pluginResult;
3) Kiedy metoda async java kończy zwracanie innego wyniku wtyczki w ten sposób:
PluginResult result = new PluginResult(PluginResult.Status.OK, data);
result.setKeepCallback(false);
this.success(result, this.myCallbackId);
Jak powiedziałem, możesz spojrzeć na kod w Githubie, aby zobaczyć, jak używamy tego do połączenia i baterii.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-21 13:02:48
W ten sposób rozwiązuję takie problemy jak twoje.
1) Utwórz i skojarzyć interfejs JavascriptInterface do widoku sieci Web. JavascriptInterface to po prostu klasa, w której możesz zadeklarować jakąś metodę Javy, której chcesz użyć z JS.
public class JSInterface() {
private final CountDownLatch latch = new CountDownLatch(1);
public void waitForProceed() {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void canProceed() {
latch.countDown();
}
}
2) w Twoim Asynctasku, na końcu metody onPostExecute()
, musisz wywołać metodę canProceed()
, aby powiadomić JSInterface, że może ona wyjść z metody waitForProceed()
.
public class MyAsyncTask extends AsyncTask<.......> {
private JSInterface jsi;
... // other class property
public MyAsyncTask(JSInterface jsi) {
...
//do what you want with other class property
this.jsi = jsi;
}
@Override
public ... doInBackground(...) {
...
//do something
}
@Override
public void onPostExecute(...) {
...
//do something
jsi.canProceed();
}
}
3) w swojej aktywności musisz powiązać obiekt JSInterface z Twoim WebView:
WebView mWebView;
...
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new JSInterface(), "JSIface");
4) Wreszcie, w JS, można wywołać AsyncTask (Nie wiem jak to nazwać, ale domyślam się, że używasz somthing jak JSInterface) i po wywołaniu waitForProceed()
metoda:
startAsyncTask(); //somehow
JSIface.waitForProceed();
Mam nadzieję, że to rozwiąże twój problem;)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-20 12:23:44
Oto szczegółowy przykład:
Stwórzmy interfejs, który powinien zostać wywołany, gdy AsyncTask
zakończy działanie, a. E kiedy onPostExecute
zostanie wywołany.
W moim przypadku pobieramy dane JSONArray
MyTaskListenerItf.java
public interface GroupTaskListenerItf {
public void onTaskDone(JSONArray groupArray);
}
AsyncTask
szablon wygląda następująco:
MyBuildTask.java
public class MyBuildTask extends AsyncTask<Void, Void, SomeData>{
private MyTaskListenerItf mTl = null;
public MyBuildTask(Context context, MyTaskListenerItf tl) {
super();
this.mContext = context;
this.mTl = tl;
}
@Override
protected SomeData doInBackground(Void... params) {
/* ... */
}
@Override
protected void onPostExecute(WmTransferItem transferItem) {
// ...
if(this.mTl != null){
JSONArray data = new JSONArray("");
this.mTl.onTaskDone(data);
}
// ..
}
}
Więc teraz nasza CordovaPlugin
klasa powinna wyglądać następująco:
MyCordovaPlugin.java
public class MyCordovaPlugin extends CordovaPlugin implements GroupTaskListenerItf {
// we need this callback when Task will finish
private CallbackContext mMyCallbackContext = null;
@Override
public boolean execute(String action, JSONArray args,CallbackContext callbackContext) throws JSONException {
if("runMe".equals(action)){
final GroupTaskListenerItf gt = this;
mMyCallbackContext = callbackContext;
// pass our 'GroupTaskListenerItf' interface to async class
MyBuildTask task = new MyBuildTask(cordova.getActivity(), gt);
task.execute();
PluginResult pluginResult = new PluginResult(PluginResult.Status.NO_RESULT);
pluginResult.setKeepCallback(true);
callbackContext.sendPluginResult(pluginResult);
}
else{
this.cordova.getThreadPool().execute( new Runnable() {
public void run() {
// BTW, here you might run something else out of UI Thread
}
});
}
}
/* ... */
@Override
public void onTaskDone(JSONArray data) {
if (this.mGroupCallbackContext != null) {
PluginResult result = new PluginResult(PluginResult.Status.OK, data);
result.setKeepCallback(false);
this.mMyCallbackContext.sendPluginResult(result);
}
}
To wszystkie.
Mam nadzieję, że to komuś pomoże.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-02 14:41:18