Android多线程的使用方式


众所周知,Android中更新UI的操作只能在Main Thread(UI Thread)中进行,而耗时的操作要放在子线程中,这是因为UI线程是和用户交互的,必须有较高的响应速度,如果主线程执行一些耗时操作,界面就会卡顿,甚至无法响应。当子线程想更新UI的时候,必然要有机制通知UI线程操作。本文先介绍Android多线程的简单使用,每种方法的详解之后会写总结。

读本篇文章之前需要对java线程有一定的认识,不熟悉的可以查看java线程基础知识总结

Handler + Thread + Message

在主线程中创建Handler对象,并重写handleMessage()方法,负责消息的发送和接收处理,子线程通过调用Handler对象的send或post(post内部也是调用send的方法)方法把消息发送给主线程,Handler接收到消息后,根据消息的种类作出相应的操作。

注:这里可能有人不明白,Handler发送消息,Handler又负责接收消息并处理?是不是多此一举了,其实并不是,这里Handler发送消息和接收消息处理是发生在不同线程中的。比如子线程执行完耗时任务了,想更新UI提醒用户已执行完毕,但子线程不能操作UI,所以他只能发送一个消息给主线程,主线程接收消息并根据消息类型执行指定的操作。

例子
activity_handler_example.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    tools:context=".thread.HandlerExampleActivity">

    <Button
        android:layout_centerInParent="true"
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="点我加载"/>

    <TextView
        android:id="@+id/text"
        android:layout_below="@+id/button"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="还没开始加载!" />

    <ProgressBar
        android:layout_below="@+id/text"
        android:id="@+id/progress_bar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:progress="0"
        android:max="100"
        style="?android:attr/progressBarStyleHorizontal"/>
</RelativeLayout>

HandlerExampleActivity

public class HandlerExampleActivity extends AppCompatActivity {
   
    private Handler mHandler;
    private Button mBtnLoad;
    private TextView mTvStatus;
    private ProgressBar mProgressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler_example);

        initView();
        setClick();

        // 新建Handler对象重写handleMessage方法
        mHandler = new Handler() {
   
            @Override
            public void handleMessage(@NonNull Message msg) {
   
                switch (msg.what) {
   
                    case 1:
                        mProgressBar.setProgress((int)msg.obj);
                        mTvStatus.setText("已加载" + (int)msg.obj + "%");
                        break;
                    case 2:
                        mTvStatus.setText("加载完毕");
                }
            }
        };
    }

    private void initView() {
   
        mBtnLoad = findViewById(R.id.button);
        mTvStatus = findViewById(R.id.text);
        mProgressBar = findViewById(R.id.progress_bar);
    }

    private void setClick() {
   
        mBtnLoad.setOnClickListener(new View.OnClickListener() {
   
            @Override
            public void onClick(View v) {
   
                new Thread(new MyTask()).start();
            }
        });
    }

    private class MyTask implements Runnable {
   

        @Override
        public void run() {
   
            int progess = 0;
            while (progess < 100){
   
                progess++;
                Message msg = Message.obtain();
                msg.what = 1;
                msg.obj = progess;
                mHandler.sendMessage(msg);
                try {
   
                    Thread.sleep(50);
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }
            }

            Message msg = Message.obtain();
            msg.what = 2;
            mHandler.sendMessage(msg);
        }
    }
}

在这里插入图片描述
上面的代码很简单,点击按钮开启子线程,子线程不断发送消息给UI线程,UI线程根据消息类型作出不同的UI操作。

需要注意的是,如果在子线程中创建Handler

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值