Android Phonegap: Notificar a javascript cuando se termina un AsyncTask

En mi aplicación, cuando el usuario haga clic en un botón en webview, un complemento phonegap se llamará para activar un asynctask para descargar el archivo de Internet. Ahora quiero enviar una señal de nuevo a la parte javascript cuando el asynctask está terminado. Pero no sé cómo hacerlo, porque mi complemento ya había enviado algo antes de que el asynctask se haya terminado. ¿Alguien sabe cómo puedo notificar mi parte javascript sin complemento en Phonegap?

También hice esta pregunta en Phonegap Grupo de Google, aquí está la respuesta de Simon Mac Donald. Funciona perfectamente para mí:


Puede manejar esta situación utilizando la API de complemento con bastante facilidad. Se implementa en los elementos básicos del API Conexión y batería. Lo que debe hacer es:

1) En su método execute () de su plugin, guarde el callbackId que obtiene.

2) Devolver un resultado de plugin NO_RESULT y establecer keep callback id a true.

PluginResult pluginResult = new PluginResult(PluginResult.Status.NO_RESULT); pluginResult.setKeepCallback(true); return pluginResult; 

3) Cuando termina el método async java devolver otro resultado de plugin como este:

  PluginResult result = new PluginResult(PluginResult.Status.OK, data); result.setKeepCallback(false); this.success(result, this.myCallbackId); 

Como he dicho, usted puede mirar el código en GitHub para ver cómo estamos utilizando esto para la conexión y la batería.


Así es como resuelvo problemas como tu.

1) Cree y asocie un JavascriptInterface a su WebView. A JavascriptInterface es simplemente una clase dentro de la cual puede declarar algún método Java que desee utilizar de 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) En su AsyncTask, al final del método onPostExecute() , tiene que llamar al método canProceed() para notificar a JSInterface que puede salir del método 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) En su actividad tiene que asociar el objeto JSInterface a su WebView:

 WebView mWebView; ... mWebView.getSettings().setJavaScriptEnabled(true); mWebView.addJavascriptInterface(new JSInterface(), "JSIface"); 

4) Finalmente, en JS, puedes llamar a AsyncTask (no sé cómo lo llamas, pero supongo que usas somthing como un JSInterface) y después del método waitForProceed() llamada:

 startAsyncTask(); //somehow JSIface.waitForProceed(); 

Espero que resuelva su problema;)

He aquí un ejemplo detallado:

Permite crear alguna interfaz que se debe llamar cuando AsyncTask terminará las cosas, ae cuando onPostExecute llamado.

En mi caso, obtenemos algunos datos de JSONArray

MyTaskListenerItf.java

 public interface GroupTaskListenerItf { public void onTaskDone(JSONArray groupArray); } 

La plantilla AsyncTask ve así:

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); } // .. } } 

Así que ahora nuestra clase CordovaPlugin debería verse así:

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); } } 

Eso es todo.

Espero que ayude a alguien.

  • ¿Cómo puedo saber si se produjo una excepción Javascript en una aplicación PhoneGap? (Androide)
  • ¿Cómo resaltar el texto permanentemente en la vista web de Android?
  • Llamadas Javascript desde Android usando PhoneGap
  • Cómo pasar un objeto Blob de javascript a Android?
  • iphone, ipad, android javascript imprimir ()
  • JQuery - Permitir teclado Autoshow en móvil
  • Acceso-Control-Permitir-Origen Error En Android 4.1
  • ¿Cómo puedo desarrollar aplicaciones móviles usando HTML5?
  • "Evalúe esta aplicación" en Google Store Store en la aplicación de Ionic
  • La alerta de JavaScript no funciona en Android WebView
  • Cómo reproducir canciones en Android - phonegap
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.