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()");
            }
        });
    }

posted @   在天边偷看小天使  阅读(35)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示