Rediska Rediska - 1 year ago 100
Android Question

Posting on UI thread from javascript interface

I am trying to post a Runnable to be executed on the main thread, from a javascript interface method.
I do it in three different ways which I believe all should work.
But in fact only two of them work.
For some reason, does not work.
I want an explanation why.

This is the source:

package com.package1.test;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebSettings;
import android.webkit.WebView;

public class MainActivity extends AppCompatActivity {

protected void onCreate(Bundle savedInstanceState) {
WebView webView = new WebView(this);
WebSettings ws = webView.getSettings();

webView.addJavascriptInterface(new JavaObject(),"obj");
webView.loadUrl("javascript:obj.test(0); ");

static class Runner implements Runnable {
private String msg;

public Runner(String msg) {
this.msg = msg;

public void run() {
String name = Thread.currentThread().getName();
Log.i("Test","Execute on thread "+name+": "+msg);

class JavaObject {
private View view;

public JavaObject() {
this.view = new View(MainActivity.this);

public void test(final int value) {
Log.i("Test","called on "+Thread.currentThread().getName()+" thread");
doOnMainThread1(new Runner("Method 1"));
doOnMainThread2(new Runner("Method 2"));
doOnMainThread3(new Runner("Method 3"));

public void doOnMainThread1(Runnable r) {;

public void doOnMainThread2(Runnable r) {
new Handler(Looper.getMainLooper()).post(r);

public void doOnMainThread3(Runnable r) {


This is the log output:

08-31 19:34:02.703 22359-22419/com.package1.test I/Test: called on JavaBridge thread
08-31 19:34:02.771 22359-22359/com.package1.test I/Test: Execute on thread main: Method 2
08-31 19:34:02.772 22359-22359/com.package1.test I/Test: Execute on thread main: Method 3

Answer Source r) will be trigger only if this view is attached to window (you need to add it to layout). Otherwise view will collect those Runnable in RunQueue. And when it finally attached to window it will execute those post actions from RunQueue. For more info take a look on r) implementation