当前位置:  开发笔记 > 编程语言 > 正文

Android的WebView中的JavascriptInterface:对JS的多次调用会导致死锁

如何解决《Android的WebView中的JavascriptInterface:对JS的多次调用会导致死锁》经验,为你挑选了0个好方法。

这是我使用的整个Java代码.我将在下面详细解释......

public class Test7 extends Activity {
    //debug
    private final static String TAG = "JSInterface";

    private WebView wv;

    private class JSInterface {
        private WebView wv;

        // Variables to manage interfacing with JS
        private String returnValue;
        private boolean canReadReturnValue;
        private Lock lockOnJS;
        private Condition condVarOnJS;

        public JSInterface (WebView wv) {
            this.wv = wv;       
            this.canReadReturnValue = false;
            this.lockOnJS = new ReentrantLock();
            this.condVarOnJS = lockOnJS.newCondition();
        }

        public void setReturnValue(String ret) {
            lockOnJS.lock();
            returnValue = ret;
            canReadReturnValue = true;
            condVarOnJS.signal();
            lockOnJS.unlock();
            Log.d(TAG, "returnValue = " + returnValue);
        }

        public String getReturnValue() {
            Log.d(TAG, "enter in getReturnValue");
            lockOnJS.lock();
            while (!canReadReturnValue) {
                try {
                    Log.d(TAG, "get wait...");
                    condVarOnJS.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            lockOnJS.unlock();
            Log.d(TAG, "returnValue: " + returnValue);
            return returnValue;
        }

        public String getNewString() {
            wv.loadUrl("javascript:JSInterface.setReturnValue(createNewString())");         
            return getReturnValue();
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        wv = (WebView) findViewById(R.id.webView1);
        wv.getSettings().setJavaScriptEnabled(true);
        wv.addJavascriptInterface(new JSInterface(wv), "JSInterface");
        wv.loadUrl("file:///android_asset/prova7.html");
    }

    public void button1(View v) {
        wv.loadUrl("javascript:func('1')");
    }
}

它似乎工作正常.

您可以看到我有一个按钮(我们可以调用button1),然后单击它,它会尝试执行一个名为func()的JS方法.

public void button1(View v) {
    wv.loadUrl("javascript:func('1')");
}

在这个JS方法中,我必须调用另一个Java方法.这是代码:

function func(id) {
    document.getElementById(id).innerHTML = JSInterface.getNewString();
}

我需要将JSInterface.getNewString()的结果返回给innerHTML变量.

JSInterface.getNewString()的代码是这样的:

public String getNewString() {
    wv.loadUrl("javascript:JSInterface.setReturnValue(createNewString())");         
    return getReturnValue();
}

您可以看到我使用该方法setReturnValuegetReturnValue返回另一个JS方法返回的值.这是代码:

function createNewString() {
    return "my New String";
}

问题是当我尝试设置returnValue时,永远不会执行createNewString函数!如果我添加一个console.log()行,我的logCat什么都不显示!

我不明白为什么会这样.

推荐阅读
放ch养奶牛
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有