Webview Methods on Same Thread Error

WebView methods on same thread error

The JavaScript method is executed on a background (i.e. non-UI) thread. You need to call all Android View related methods on the UI thread. You can achieve what you need with:

mWebView.post(new Runnable() {
@Override
public void run() {
mWebView.loadUrl(...).
}
});

Which will post the task to run on the UI thread.

Kotlin: All WebView methods must be called on the same thread

You should use Runnable and Post to WebView Handler.

myWebView.post(Runnable {
myWebView.loadUrl("file:///android_asset/index.html")
})

Android returns methods must be called on same thread error

As you said, when you call methods from JS to the JavaBridge and then to your class from a non-ui Thread, you have to use listeners/callbacks. When you have done your loadUrl, call you listener to pass the desired String url.

In this Example, I've defined an an inner interface with the onGetWebViewUrl listener. I've registered the listener by implementing the interface in the same class, so I can call it easily.

For example :

public class WebViewProxy implement WebViewListener {

private WebView mWebView;

...

@JavascriptInterface
public void onJsStuff(){
webView.post(new Runnable() {
public void run() {
mWebView.loadUrl("javascript:" + s + ";");
WebViewProxy.this.onGetWebViewUrl(mWebView.getUrl());
}
});
}

@Override
public void onGetWebViewUrl(String url){
// call method 2 with this url
}

public interface WebViewListener {

void onGetWebViewUrl(String url);
}
}

A WebView method was called on thread 'FinalizerDaemon' BUT MY APP HAS NO WEBVIEW

Apparently you're using an in-app ads SDK that uses a WebView (Admob?) See com.google.android.gms.ads.internal.webview....

Plus, from my experience with WebView and StrictMode, the fact you're getting this behavior probably it is not a bug of the Ads SDK: I our app we had to disable some checks (or reduce the penalty to log) in order to work around the problem (we do use WebView, and the WebView itself creates issues with StrictMode because of disk access done from UI thread and similar issues).

WebView Methods is not called in android

The warning is telling you everything. You are calling the webview methods directly. That means you are calling them on WebViewCoreThread. You have to call them on the UI Thread that means in the Activity which uses this webview.

Like:

WebView wv = (WebView)findViewById(id);
wv.setJavaScriptEnabled(true);
wv.setJavaScriptCanOpenWindowsAutomatically(true);
wv.setPluginsEnabled(true);
wv.loadUrl("javascript:android.selection.longTouch();");

WebView - Threads

JavascriptInterfacemethods are called on background thread and not on UI thread. While dealing with UI, you need to use main UI thread.

Since you are executing it in separate class, you need to pass Activity object and then in all your JavascriptInterface methods:

Change the WebAppInterface class as follows:

public class WebAppInterface {
Activity activityObj;
WebView webview;

/** Instantiate the interface and set the context */
WebAppInterface(Activity activityObj, WebView w) {
mContext = c;
this.activityObj = activityObj;
}
...
}

and runOnUiThread as follows:

activityObj.runOnUiThread(new Runnable() {
@Override
public void run() {
if (Build.VERSION.SDK_INT >= 19 /*Might need 21*/) {
webview.evaluateJavascript(script, null);
}else {
webview.loadUrl(script);
}
}
});

Alternatively you can implement some callback interface and perform action in Activity itself as follows:

public interface Callback {
void loadLocalExternal(boolean isExternal);
//define other methods.
}

MainActivity.java

public class MainActivity extends AppCompatActivity implements Callback{

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

WebView webview = (WebView)findViewById(R.id.webView);
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebChromeClient(new WebChromeClient());
webview.loadUrl("file:///android_asset/www/index.html");

webview.addJavascriptInterface(new WebAppInterface(this, this), "Android");
}

@Override
public void loadLocalExternal(boolean isExternal){
runOnUiThread(new Runnable() {
@Override
public void run() {
//Do your action here
}
});
}

}

WebAppInterface.java

public class WebAppInterface {
Context mContext;
private final Callback callback;

/** Instantiate the interface and set the context */
WebAppInterface(Context c, Callback callback) {
mContext = c;
this.callback = callback;
}
@android.webkit.JavascriptInterface
public String loadLocalExternal(boolean isExternal) {
callback.loadLocalExternal(isExternal);
}
...
}

Reloading a WebView with a JavaScript call from a loaded web page

Loading a page in a WebView componenet (or reloading) needs to be done on the UI thread for some reason, so simply wrapping the reload call in runOnUiThread resolves this issue.

    @JavascriptInterface
public void reloadSite(){
Toast.makeText(mContext, getString(R.string.reloadingWebApp), Toast.LENGTH_LONG).show();
runOnUiThread(new Runnable() {
@Override
public void run() {
mWebView = (WebView) findViewById(R.id.activity_main_webview);
mWebView.loadUrl(getString(R.string.web_app_url));
}
});
}


Related Topics



Leave a reply



Submit