javascript - 后台线程卡住 WebView

标签 javascript java android multithreading webview

我将 JavaScript 接口(interface)注入(inject)到我的 WebView 中,一旦我到达我在 JavaScript 中定义的 native 方法,如果卡住WebView直到我返回一个值。 例如:

在此示例中,WebView 卡住 8 秒。我还仔细检查了它不是主线程,它确实不是主线程,所以我只是看不出它会卡住 WebView 的原因。

myWebView.addJavascriptInterface( new WebViewHandler.JavaScriptInterface(), "webCallHandler" );

public class JavaScriptInterface
{
    @JavascriptInterface
    public String jsToAndroidNativeFunc(String Data)
    {

        Callable<String> task = new Callable<String>() {
            @Override
            public String call() throws Exception {
                try {
                    if( Looper.getMainLooper() == Looper.myLooper() )
                        Log.d("TAG","Main Thread");
                    else
                        Log.d("TAG","Not Main Thread");
                    TimeUnit.SECONDS.sleep(8); // the webview is now stuck during these 8 seconds
                    return "123";
                }
                catch (InterruptedException e) {
                    throw new IllegalStateException("task interrupted", e);
                }
            }
        };

        ExecutorService executor = Executors.newFixedThreadPool(1);
        Future<String> future = executor.submit(task);

        try {
            return future.get();
        }
        catch (InterruptedException e) {
            e.printStackTrace();
            return "111";
        } catch (ExecutionException e) {
            e.printStackTrace();
            return "111";
        }
    }
}

最佳答案

更新

此代码使用以下 javascript 代码调用:

var response = webCallHandler.jsToAndroidNativeFunc(request.data);

这正是导致 UI 卡住的原因,因为 javascript is single-threaded .我们必须使用回调进行异步调用。就像 Ajax。

原始答案

我不知道js android 接口(interface)。我所知道的是您的功能正在等待答案。 IE。 Future.get() 是一个阻塞函数。摘自API :

Waits if necessary for the computation to complete, and then retrieves its result.

我建议让这个 jsToAndroidNativeFunc 无效并添加一些回调。另外,我建议在方法之外定义一个执行器。例如。在类或应用级别:

public class JavaScriptInterface
{

    private final ExecutorService EXECUTOR = Executors.newFixedThreadPool(1);

    @JavascriptInterface
    public void jsToAndroidNativeFunc(String Data, Callback callback)
    // I just made up the Callback class. There must be a way to do so with webview too.
    {

        Callable<String> task = new Callable<String>() {
            @Override
            public String call() throws Exception {
                try {
                    // ...
                    callback.call("123"); // no return, but call the js callback
                }
                catch (InterruptedException e) {
                    throw new IllegalStateException("task interrupted", e);
                }
            }
        };

        EXECUTOR.submit(task); // using the static executor
        // no Future, no return either. Js side will execute asynchronously.
    }

关于javascript - 后台线程卡住 WebView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43250490/

相关文章:

java - 使用gradle build jar描述创建具有依赖项的jar文件

java - 设置 RCP 程序的系统属性

javascript - 使用 Sequelize.js findAll 对连接表中的字段进行排序的正式且正确的语法

javascript - 如何使用 for in 循环动态填充数组

java - 使用桌面的默认应用程序打开存储在 jar 文件中的 PDF 文件

android - checkmarx 报告了 Volley 的 REFELCTED_XSS_ALL_CLIENT

java - 连接到 Mysql 数据库 - JDBC 或 PHP

javascript - 使用文档片段渲染 Backbone View 会中断事件处理

php - 自动完成问题

android - 打开 NFC 模拟器使用