android子线程中不能更新UI,子线程中执行runOnUIThread()调回主线程更新UI基本没有时延,但是如果等子线程结束再在主线程更新UI会有时延

android子线程中不能更新UI,子线程中执行runOnUIThread()调回主线程更新UI基本没有时延,但是如果等子线程结束再在主线程更新UI会有时延

在这里插入图片描述

操作背景:把okHttp的请求放在static方法中执行,由okhttp的enqueue方法提供子线程

点击指定按键之后将执行下面代码中的test_callbackOkHttp()方法

   private void showResponse(final String response){
        runOnUiThread(new Runnable() {
            /*安卓不允许在子线程中进行UI操作,
            所以调用runOnUIThread将线程切换到主线程然后再更新UI元素*/
            @Override
            public void run() {
                responseText.setText(response);
            }
        });
    }

    public static void sendOkHttpRequest(String address,okhttp3.Callback callback){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(address)
                .build();
        client.newCall(request).enqueue(callback);
        //callback参数为okhttp库中自带的回调接口,newCall()之后没有直接执行execute()方法
        //而是调用enqueue方法,并把callback传入,在enqueue方法内部已经开启了子线程
        //会在子线程中去执行HTTP请求,并将最终结果回调到callback中
    }

    private void callbackInOkHttp(String address){
        MainActivity.sendOkHttpRequest(address,new okhttp3.Callback(){
            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                responseData = response.body().string();
                //在子线程中使用runONUIThread调回主线程去更新UI
                /*showResponse(responseData);*/
            }

            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                e.printStackTrace();
                Log.e("static okHttp","Error in OnFailure()");
            }
        });
    }

    private void test_callbackInOkHttp(){
        String address = editText.getText().toString();
        callbackInOkHttp(address);
        //在子线程结束之后,执行更新UI的操作
        /*if(responseData!=null){
            responseText.setText("验证okhttp的static方法(获取的String数据通过callback从enqueue方法内部已经定义的子线程中回调显示)的结果如下:\n"
                    +responseData);
        }*/
    }
}

如果在等子线程执行结束之后再更新UI,会有因为子线程要执行完而产生的延时导致第一次按键没有东西显示,而且不会在等上一会儿后显示东西,这时如果第二次按键才会立即显示获取的数据

private void test_callbackInOkHttp(){
        String address = editText.getText().toString();
        callbackInOkHttp(address);
        //这里更新UI
        if(responseData!=null){
            responseText.setText("验证okhttp的static方法(获取的String数据通过callback从enqueue方法内部已经定义的子线程中回调显示)的结果如下:\n"
                    +responseData);
        }
    }

如果在子线程中直接使用runONUIThread去更新UI,可以在第一次按键之后立即更新UI

private void showResponse(final String response){
        runOnUiThread(new Runnable() {
            /*安卓不允许在子线程中进行UI操作,
            所以调用runOnUIThread将线程切换到主线程然后再更新UI元素*/
            @Override
            public void run() {
                responseText.setText(response);
            }
        });
    }

private void callbackInOkHttp(String address){
        MainActivity.sendOkHttpRequest(address,new okhttp3.Callback(){
            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                responseData = response.body().string();
                //在子线程中使用runONUIThread调回主线程去更新UI
                showResponse(responseData);
            }

            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                e.printStackTrace();
                Log.e("static okHttp","Error in OnFailure()");
            }
        });
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值