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?

Author: Peacemoon, 2011-10-13

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.


 35
Author: Peacemoon,
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;)

 2
Author: Vito Gentile,
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.

 0
Author: Maxim Shoustin,
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