主线程更新UI与Only the original thread that created a view hierarchy can touch its views.

本文介绍了一种在Android应用开发中解决子线程更新UI的方法。通过使用Handler、View.post、runOnUiThread等机制,可以避免报错“Only the original thread that created a view hierarchy can touch its views”,并给出了具体示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

报错:

Only the original thread that created a view hierarchy can touch its views.

原因:

子线程中不能更新ui操作

主线程更新UI方式:

更新UI方法一:handler.post
更新UI方法二:view.post
更新UI方法三:runOnUiThread
更新UI方法四:handler.handleMessage

示例:

public class ThreadActivity extends FragmentActivity {

    /*更新UI方法四:handler.handleMessage*/
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            switch (msg.what) {
                case 0:
                    Log.e("111", "开始下载");
                    break;
                case 1:
                    Log.e("111", "设置图片");
                    mIv.setImageBitmap((Bitmap) msg.obj);
                    Log.e("111", "handler.handleMessage为:" + Looper.getMainLooper().getThread());//Thread[main,5,main]
                    Log.e("111", "handler.handleMessage 名称为:" + Thread.currentThread().getName());//main
                    break;
                case 2:
                    Log.e("111", "设置完毕");
                    break;
            }

        }
    };

    private ImageView mIv;

    private String path = "https://github.com/Ablexq/MyTabs/raw/master/pic/a.jpg";

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_thread);

        mIv = ((ImageView) this.findViewById(R.id.iv));

        Log.e("111", "主线程(UI线程)为:" + Looper.getMainLooper().getThread());//Thread[main,5,main]
        Log.e("111", "主线程(UI线程)名称为:" + Thread.currentThread().getName());//main

        new Thread(new Runnable() {//子线程

            @Override
            public void run() {

                //下载前
                handler.sendEmptyMessage(0);

                Bitmap bm = null;
                try {
                    HttpURLConnection huc = (HttpURLConnection) new URL(path).openConnection();
                    huc.connect();

                    if (huc.getResponseCode() == 200) {
                        bm = BitmapFactory.decodeStream(huc.getInputStream());
                    }


                    //设置图片
                    Message message = Message.obtain();
                    message.obj = bm;
                    message.what = 1;
                    handler.sendMessage(message);

                    //设置图片后
                    handler.sendEmptyMessage(2);

                } catch (IOException e) {
                    e.printStackTrace();
                }

                Log.e("111", "new Thread线程为:" + Thread.currentThread());//Thread[Thread-5,5,main]
                Log.e("111", "new Thread线程 名称为:" + Thread.currentThread().getName());//Thread-5

                final Bitmap finalBm = bm;

                /*更新UI方法一:handler.post*/
//                handler.post(new Runnable() {
//                    @Override
//                    public void run() {
//                        Log.e("111", "handler.post线程为:" + Thread.currentThread());//Thread[main,5,main]
//                        Log.e("111", "handler.post线程 名称为:" + Thread.currentThread().getName());//main
//                        mIv.setImageBitmap(finalBm);
//                    }
//                });


                /*更新UI方法二:view.post*/
//                mIv.post(new Runnable() {
//                    @Override
//                    public void run() {
//                        Log.e("111", "view.post线程为:" + Thread.currentThread());//Thread[main,5,main]
//                        Log.e("111", "view.post线程 名称为:" + Thread.currentThread().getName());//main
//                        mIv.setImageBitmap(finalBm);
//                    }
//                });

                /*更新UI方法三:runOnUiThread*/
//                runOnUiThread(new Runnable() {
//                    @Override
//                    public void run() {
//                        Log.e("111", "runOnUiThread线程为:" + Thread.currentThread());//Thread[main,5,main]
//                        Log.e("111", "runOnUiThread线程 名称为:" + Thread.currentThread().getName());//main
//
//                        mIv.setImageBitmap(finalBm);
//                    }
//                });

            }
        }).start();

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值