latch(用于等待异步响应)冻结WebView(和UI)

BVt*_*Vtp 7 java user-interface multithreading android asynchronous

我有一个应用程序,在整个布局上显示webview.有时我需要调用异步方法,异步操作由三方sdk完成,然后我等待一段时间直到我得到对指定监听器的响应.我用一个锁存器解决了它 - 一旦在监听器中收到响应,我就计算掉锁存器,然后启动方法可以继续这个响应.不幸的是,当我这样做时,WebView被卡住了.我想象原生UI会被卡住,但我没想到webview也会被冻结.怎么能克服?

为了更清楚,这是一个例子.我需要ajaxFunc等待MyAsyncListener获得某个响应,然后返回这个确切的响应.

JS注入webview的一部分:

var response = jsHandler.ajaxFunc(request.data);
Run Code Online (Sandbox Code Playgroud)

我有一个名为变量的全局变量response.

public class JavaScriptInterface
{
     @JavascriptInterface
     public String ajaxFunc(String data)
     {
         return MyUtils.handleData( data );
     }
}
Run Code Online (Sandbox Code Playgroud)

handleData方法:

 public String handleData( String data )
 {
     SomeClass.startAsyncRequest(); // starts the async request, response is to come at the listener's callbacks .

     latch = new CountDownLatch(1);
     try {
         latch.await(30, TimeUnit.SECONDS);
     }
     catch (InterruptedException e) {
         e.printStackTrace();
     }

     return response;
   }
Run Code Online (Sandbox Code Playgroud)

现在,一旦handleData函数调用一个异步执行某个函数的函数,异步函数就会在一些Listener中返回一些答案:

myAsyncListener = new MyAsyncListener() {
    @Override
        public Response handleEvent(CustomEvent event) {
            //Now I need to return this 'event' back to the handData/ajaxFunc function <-- 

            response = event.getName();
            latch.countDown();

        }
    });
Run Code Online (Sandbox Code Playgroud)

nan*_*ito 4

我需要 ajaxFunc 等待,直到 MyAsyncListener 获得特定响应,然后返回这个确切的响应。

由于您正在分派异步请求,因此您不应期望响应会到达启动异步代码所进行的同一方法调用中。如果这样做,调用者线程将阻塞,直到异步响应到达,也就是说,它根本不会是异步的。

您可以将代码重新设计为如下所示:

public class JavaScriptInterface {
    @JavascriptInterface
    public void ajaxFunc(String data) {
        // draw a waiting animation or something
        MyUtils.handleData(data);
    }
}
Run Code Online (Sandbox Code Playgroud)
public void handleData(String data) {
    SomeClass.startAsyncRequest();
}
Run Code Online (Sandbox Code Playgroud)
myAsyncListener = new MyAsyncListener() {
    @Override
    public void handleEvent(CustomEvent event) {
        // Do what you need to do
        // (update UI, call javascript etc.).
        //
        // Mind the thread that will execute this callback
        // to prevent multithreading issues.
    }
}
Run Code Online (Sandbox Code Playgroud)