Question

Since Webworkers is only implemented from Android 4.4 onwards, is it possible to have a wrapper in the application code that provides this functionality to the contained WebView?

An example on how to solve this would really help.

Thanks,
Rajath

Était-ce utile?

La solution

I guess you are talking about running a javascript code block in the background, i.e. different thread. Had tried doing that using RhinoJS on Android. Tested on Android 2.2 and above

https://github.com/devthon/SilentJSAndroid

The main features are

  1. Execute Javascript code without browser context
  2. Execute Javascript code from a script file
  3. Load other JS files in the same context
  4. Execute a method in the background thread and return a result
  5. Execute a Object.Method() call
  6. Execute a prototype method call
  7. Run long running script in the background after app is closed.

May not be a full fledged Web worker as such, since it doesn't have API to check the status in between. But that can be still added to the interface I believe.

If this is the direction you are looking for, I can explain more on how it is done.

Autres conseils

How much of the Worker spec do you need to implement, and how flexible does the implementation need to be? You could probably get basic functionality up and running using a JavaScript interface[1] and spawning threads natively from Java. However this will get complex quite quickly.

Perhaps if you can describe what you are using workers for I might be able to offer a different/better suggestion.

[1] http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)

--

Adding some pseudo code

In JavaScript spawn a Java worker thread:

var worker_id = window.Android.spawnWorker();

In JavaScript, run a task on that worker:

var task_id = window.Android.doAdditionOnWorker(2,2, worker_id);

Handle the result in JavaScript

function onReceiveResultForWorkerTask(task_id, result) {
    alert("the answer was " + result);
}

Java side:

public int spawnWorker() {
    HandlerThread worker = new HandlerThread();
    worker.start();
    Handler h = new Handler(worker.getLooper()) {
        @Override
        handleMessage(Message msg) {
           switch(msg.what) 
           case ADD:
               // calculate the answer and send back to JS via UI thread
               // Unpack parameters and task id from Message               
               mWebView.post(new Runnable(
                   public void run() {
                       mWebView.loadUrl("javascript:onReceiveResultForWorkerTask(task_id, " + (a+b) +");");
                   }
               )
        }
    };

    mWorkerMap.put(mWorkerId++, h);
    return mWorkerId;
}

public int doAdditionOnWorker(int a, int b, int worker_id) {
    Handler h = mWorkerMap.get(worker_id);
    Bundle b = new Bundle();
    int task_id = mTaskId++;
    // pack arguments and task_id into the bundle
    h.postMessage(Message.obtain(h, ADD, b);
    return task_id;
}

Don't forget to go through and tear down all the worker threads that you spawn when the app doesn't need them anymore. Depending on how many workers you need you might also prefer to use a thread pool rather than creating new threads every time.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top