Android--线程与异步消息处理机制

熟悉开发的朋友,对多线程编程一定不会陌生。当我们需要执行一些耗时操作时,比如说发起一条网络请求,考虑到网速以及一些其他原因,服务器不一定会立刻响应我们的请求。如果不将这类操作放到子线程里去运行,就可能会导致主线程阻塞,影响用户的正常使用。但是,并不是所有操作都能够在子线程中进行的,接下来我们就通过一个实例来探究一下。
首先我们新建一个AndroidThreadTest项目,编辑activity_main.xml中的代码,如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/change_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Change Text"
        android:textAllCaps="false" />

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Hello Thread"
        android:textSize="20sp"
        android:textAllCaps="false" />


</RelativeLayout>
 
 
界面布局如下:




布局文件中就是简单的定义了两个控件,TextView用于在屏幕中央显示一个Hello World字符串。Button用于改变TextView中显示的内容。我们希望在点击Button后可以把屏幕中央的内容变成:Kevin Durant

接下来修改MainActivity中的代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private TextView text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button changeText = (Button) findViewById(R.id.change_text);
        text = (TextView) findViewById(R.id.text);
        changeText.setOnClickListener(this);
    }

    @Override
    public void onClick(View v){
        switch (v.getId()){
            case R.id.change_text:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        text.setText("Kevin Durant");
                    }
                }).start();
                break;
            default:
                break;
        }
    }

首先获取到Button和TextView控件的实例,然后在Button按钮的点击事件里面开启了一个子线程,在子线程中调用text的setText()方法将字符串的内容变成 Kevin Durant,也就是更新了子线程中的UI元素,接下来我们运行程序,然后点击Button按钮,会发现程序出现了异常,异常信息如下:



很明显,大概的意思就是,由于在子线程中更新UI导致了程序出现崩溃。也由此证明了,Android确实是不允许在子线程中进行UI操作的。但是有些时候,我们必须在子线程里去执行一些耗时任务,然后根据执行结果来更新响应的UI控件,难道我们就无法解决了吗? 当然NO!

对于这种情况,Android提供了一套异步消息处理机制,很好的解决了在子线程中进行UI操作的问题,接下来我们就来学习一下异步消息时如何解决这个问题的。

首先还是修改MainActivity中的代码:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    public static final int UPDATE_TEXT = 1;

    private TextView text;

    private Handler handler = new Handler(){

        public void handleMessage(Message msg){
            switch (msg.what){
                case UPDATE_TEXT:
                    //在这里进行UI操作
                    text.setText("Kevin Durant");
                    break;
                default:
                    break;
            }
        }
    };

我们首先定义了一个整型常量UPDATE_TEST,用于表示更新TextView这个动作。之后新增了一个Handler对象,并重写了父类的handleMessage()方法。在这里对Message对象进行具体的操作。如果发现Message的what字段值为UPDATE_TEXT。我们就来更新TextView的UI显示内容。

接着再看一下Button按钮点击事件里面子线程的代码逻辑。

@Override
public void onClick(View v){
    switch (v.getId()){
        case R.id.change_text:
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Message message = new Message();
                    message.what = UPDATE_TEXT;
                    handler.sendMessage(message); //将Message对象发送出去
                }
            }).start();
            break;
        default:
            break;
    }
}
 
 
其实,重点就是在子线程的run()方法里。先是创建了一个Message对象,并将它的字段what指定为UPDATE_TEXT,也就是可以更新UI了。然后调用Handler的sendMessage()方法将这条Message发送出去。很快,Handler就会收到这条Message,并在handleMessage()方法中对它进行处理。
而此时我们应该已经注意到了,handleMessage()方法已经是在主线程中运行了,所以我们可以放心的进行UI操作了。接下来运行程序,点击按钮,我们会发现,程序正常运行,TextView显示的内容变成了: Kevin Durant
 
 
 
 
 
 
这样,我们就通过Android异步消息处理的方法,实现了即在子线程中执行了任务,也解决了子线程中更新UI的问题。后续的章节中,我们继续来深入探讨关于Android异步消息处理机制到底是如何工作的。
 
 
 
 
 
 
 
 
 
 
 









































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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值