java - Android/Java多线程-线程直到主线程完成工作才继续

标签 java javascript android multithreading webview

标题似乎有点含糊,但我想不出另一个,所以希望我能阐明我的问题:

我正在使用Android WebView和JavascriptInterface。从我的应用程序(Java)到WebView(JavaScript)的通信是这样完成的:

webview.loadUrl("javascript:function()");

这是一个异步调用,此后应由JavaBridge-Thread处理。

另一种方法(将Javascript转换为Java)可以通过从我的Javascript代码调用JavascriptInterface mainInterface来工作。我可以在JavascriptInterface中调用用@JavascriptInterface声明的Java方法。
该调用也由JavaBridge-Thread执行。

在详细介绍之前,这里是重要的代码:

ModelActivity.java
public boolean loadPropertyIntoWebview(final String element, final String property, final String value){
    final int requestId = jsCallIndex.incrementAndGet();
    webview.loadUrl("javascript:setProperty('"+element+"', '"+property.toLowerCase()+"', '"+value+"', "+requestId+")");

    return waitForJsReturnValue(requestId, 1000);
}

private boolean waitForJsReturnValue(int index, int timeout){
    long start = System.currentTimeMillis();

    while(true){
        long elapsed = System.currentTimeMillis() - start;
        if(elapsed > timeout){
            System.out.println("JS RESPONSE TIMEOUT");
            break;
        }

        synchronized (jsReturnValueLock) {
            String value = jsReturnValues.remove(index);

            if(value != null){
                if(value.toLowerCase().equals("true")){
                    return true;
                }else{
                    System.out.println("JS BAD RESPONSE");
                    return false;
                }
            }

            long toWait = timeout - (System.currentTimeMillis() - start);
            if (toWait > 0)
                try {
                    System.out.println("WAIT NOW FOR "+toWait+" ms on index "+index);
                    jsReturnValueLock.wait(toWait);
                } catch (InterruptedException e) {
                    break;
                }
            else{
                System.out.println("JS RESPONSE TIMEOUT");
                break;
            }
        }
    }
    return false;
}

public void processJsReturnValue(int index, String value){
    System.out.println("RECEIVED ANSWER "+value+" for index "+index+" WAIT FOR UNLOCK");
    synchronized (jsReturnValueLock) {
        System.out.println("UNLOCKED FOR INDEX "+index);
        jsReturnValues.put(index, value);
        jsReturnValueLock.notifyAll();
    }
}

JavascriptInterface.java
@JavascriptInterface
public void onClick(String elementId, String property, String value){
    final String[] info = elementId.split("_");

    dbHandler.addOrUpdateOutVariable(Integer.parseInt(info[0]), Integer.parseInt(info[1]), property, value);

    ((ModelActivity)context).runOnUiThread(new Runnable() {

        @Override
        public void run() {
            actionManager.fireClickEvent(Integer.valueOf(info[0]), Integer.valueOf(info[1]));
        }
    });
}

@JavascriptInterface
public void processJsReturnValue(String index, String value){
    try{
        ((ModelActivity)context).processJsReturnValue(Integer.parseInt(index), value);
    }catch(NumberFormatException e){
        e.printStackTrace();            
    }
}

我基本上想做的是从我的JavaScript函数setProperty()(ModelActivity-> loadPropertyIntoWebview)中获取一个返回值。

在初始化期间,从主线程多次调用loadPropertyIntoWebview()方法,并且始终通过这两个processJsReturnValue()函数从JavaBridge-Thread接收答案。

另一种情况是行不通的,当用户按下我的Web View 中的按钮并调用
onClick(String elementId, String property, String value)
在我的JavascriptInterface中。函数调用
actionManager.fireClickEvent(Integer.valueOf(info[0]), Integer.valueOf(info[1]));
经历了几个我无法详细解释的类和函数,但在最后一个实例中它将调用
loadPropertyIntoWebview(final String element, final String property, final String value)

该调用也来自主线程,因为我在onClick函数中明确表示了这一点:
((ModelActivity)context).runOnUiThread(new Runnable() {

    @Override
    public void run() {
        actionManager.fireClickEvent(Integer.valueOf(info[0]), Integer.valueOf(info[1]));
    }
});

调试显示以下内容:

在初始化过程中和调用后
webview.loadUrl("javascript:setProperty('"+element+"', '"+property.toLowerCase()+"', '"+value+"', "+requestId+")");
JavaBridge-Thread立即返回processJsReturnValue()

当通过用户调用时,它不会那样做。然后直到我的超时while(true)循环完成主线程后,它才会去那里。

我希望整个过程不要太困惑,并且有人可以理解我的问题,甚至对这里发生的问题有一个想法。

最佳答案

尝试将onClick和processJsReturnValue分离为两个不同的JavascriptInterface类,创建它们的实例并独立注册。不确定,但似乎现在他们互相封锁了。

关于java - Android/Java多线程-线程直到主线程完成工作才继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30318453/

相关文章:

javascript - scala.js 与 jscala 有什么区别?

javascript - Bootstrap Carousel 不适用于 Angular ng-route

java - 检索电话号码的最佳方法?

java - Gson 序列化为 LinkedTreeMap 而不是我的实体

java swing来计算所有控件的数量

java - JSF:WAITING派对,然后重定向

javascript - 更改 iframe 的内容

android - 如何在使用真实设备时通过代码启动默认主页启动器?

javascript - 使用 Ajax 下载并打开 PDF 文件

java - 当 'key' 是两个整数时,如何输出 Java HashMap 键?