【达内课程】线程——Message(二)

这里写图片描述

xml

<LinearLayout 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:orientation="vertical"
    tools:context=".ui.MainActivity">
    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="?android:progressBarStyleHorizontal"/>

    <TextView
        android:id="@+id/tv_show_progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0/100"/>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"/>
</LinearLayout>

MainActivity

public class MainActivityextends AppCompatActivity implements View.OnClickListener {
    private ProgressBar progressBar;
    private Button button;
    private TextView textView;
    private int progress;
    private Handler handler;

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

        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        button = (Button) findViewById(R.id.button);
        textView = (TextView) findViewById(R.id.tv_show_progress);
        button.setOnClickListener(this);

        handler = new InnerHandler();
    }

    @Override
    public void onClick(View view) {
        InnerThread thread = new InnerThread();
        thread.start();
    }

    private class InnerHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            progressBar.setProgress(msg.arg1);
            textView.setText(msg.arg1+"/100");
        }
    }

    private class InnerThread extends Thread{
        @Override
        public void run() {
            for(int i=0;i<=100;i++){
                //发消息,通知主线程更新UI
                Message msg = new Message();
                msg.arg1 = i;
                handler.sendMessage(msg);
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

之前我们说过循环中尽量不要创建新对象,但是这里,如果我们写成

Message msg = new Message();
            for(int i=0;i<=100;i++){
                //发消息,通知主线程更新UI
                msg.arg1 = i;
                ......
            }

这样是不行的

子线程有100次循环,所以它会发100次消息
主线程根据子线程的msg进行消息处理时,需要一定的时间,可能第一条消息还没处理完,第二条消息已经到达,而第一个消息对象还在被使用着,所以用同一个消息对象是有问题的,所以消息对象一定是不同的

假设子线程发送到了第50个消息,主线程才处理完第1个消息,这时候我们拿第一个消息对象来用是没有问题的

解决办法

这里写图片描述

private class InnerThread extends Thread{
        @Override
        public void run() {
            for(int i=0;i<=100;i++){
                //发消息,通知主线程更新UI
                Message msg = Message.obtain();
                msg.arg1 = i;
                handler.sendMessage(msg);
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

它内部就实现了对消息对象的获取过程

优化刚才代码

public class SecondActivity extends AppCompatActivity implements View.OnClickListener {
    private ProgressBar progressBar;
    private Button button;
    private TextView textView;
    private int progress;
    private Handler handler;

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

        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        button = (Button) findViewById(R.id.button);
        textView = (TextView) findViewById(R.id.tv_show_progress);
        button.setOnClickListener(this);

        handler = new InnerHandler();
    }

    @Override
    public void onClick(View view) {
        InnerThread thread = new InnerThread();
        thread.start();
    }

    private class InnerHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            if(msg.what == MESSAGE_UPDATE_PROGRESS) {
                progressBar.setProgress(msg.arg1);
                textView.setText(msg.arg1 + "/100");
            }else if(msg.what == MESSAGE_UPDATE_COMPLETE){
                Toast.makeText(MainActivity.this,"更新进度完成",Toast.LENGTH_SHORT).show();
            }
        }
    }

    public static final int MESSAGE_UPDATE_PROGRESS = 999;
    public static final int MESSAGE_UPDATE_COMPLETE = 998;
    private class InnerThread extends Thread{
        @Override
        public void run() {
            for(int i=0;i<=100;i++){
                //发消息,通知主线程更新UI
                Message msg = Message.obtain();
                msg.what = MESSAGE_UPDATE_PROGRESS;
                msg.arg1 = i;
                handler.sendMessage(msg);
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            //发出消息,标识更新进度完成
            Message msg = Message.obtain();
            msg.what = MESSAGE_UPDATE_COMPLETE;
            handler.sendMessage(msg);
        }
    }
}

执行效果

这里写图片描述

猜你喜欢

转载自blog.csdn.net/u010356768/article/details/80578034