Android移动应用开发——第四章 Thread

Task 4-1 Thread

题目:
Make an app with 2 TextViews and 2 Buttons.
The 1st TextView shows your name and student number.
When users click the start Button, a thread runs in background and count the timer with the period of 10ms. The thread send a Message to the main UI thread by handler when the timer count updated, and the 2nd TextView shows the timer count. The timer count can be sent by the Message’s arg1 variable.
When users click the stop Button, the thread stops, and the TextView shows the last counter of the timer.
Hint:

  1. the running status in the Thread can be taken by AtomicBoolean;
  2. the timer count can be realized by Thread.sleep() function;
  3. the Handler defined in main UI can be the field of the user defined Thread class and passed by constructor.

演示
在这里插入图片描述
分析与步骤
1、Thread多线程,主要有两种是实现方法,一种是继承多线程,一种是实现Runnable接口,两种都要重写run方法,启动线程可以用run()也可以用start(),主要区别是:使用run方法是直接在主线程里面进行的,而使用start()方法则是另外开辟个线程调用
在这里插入图片描述2、Handler类:主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分在消息队列中逐一将消息取出,然后对消息进行处理,也就是发送消息和接收消息不是同步的处理。简而言之就是实现获取obtainMessage和发送sendMessage消息,值得注意的是,message一旦发送就会在定义的地方产生回调对消息进行处理
3、Bundle类:用于携带数据,类似于Map,使用键值对的方式来存放数据,其内部实际上是使用Hash Map类型来存放,可以存放各种类型的数据setString,setFloat等,通过key来获取,
注意:在回调的函数获取消息时,是先创建一个bundle来存放数据,然后通过bundle.getxxx(key)来获取具体的数据
4、AtomicBoolean原子变量的使用:由于start和stop两个按钮共用一个线程,因此使用AtomocBoolean会使得线程更加的安全,原子变量控制状态变化,类似于加锁的操作,只能使用set和get方法来获取和设置,原子变量在构造器中被初始化为false,当为true的时候可以运行
5、两个按钮的设置:由于两个按钮应该是互斥的存在,因此在一个按钮可以点击时(Enabled:“true”),另一个应该无法被点击(Enabled:“false”),避免线程发生崩溃
6、线程每0.1s休眠一次,此时将计数器数字增加0.1
7、注意:handler的包应该是:import android.os.Handler;
代码
MainActivity

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    Button bt_start,bt_stop;
    TextView tv;
    Handler handler;
    TimeCounterThread thread;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_main);
        bt_stop=findViewById(R.id.bt_stop);
        bt_start=findViewById(R.id.bt_start);
        tv=findViewById(R.id.tv);
        final Handler handler = new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(@NonNull Message msg) {
                Bundle data = msg.getData();
                float timecount = data.getFloat(TimeCounterThread.KEY_TIME_COUNT);
                tv.setText(String.format("%.2f",timecount));
                return false;
            }
        });
    bt_start.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            thread=new TimeCounterThread(handler);
            thread.start();
            bt_start.setEnabled(false);
            bt_stop.setEnabled(true);
        }
    });
    bt_stop.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            thread.stopTimer();
            bt_start.setEnabled(true);
            bt_stop.setEnabled(false);
        }
    });
    }
}

TimeCounterThread

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import java.util.concurrent.atomic.AtomicBoolean;


public class TimeCounterThread extends Thread {
    private Handler handler;
    private AtomicBoolean isRunning;
    public static final String KEY_TIME_COUNT="key_time_count";
    public float timecounter =0.0f;
    public TimeCounterThread(Handler handler) {
        this.handler = handler;
        this.isRunning=new AtomicBoolean(false);
    }

    @Override
    public void run() {
        super.run();
        isRunning.set(true);
        while(isRunning.get()){
            try {
                Thread.sleep(100);
                timecounter+=0.10f;
                sendMessage();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    private void sendMessage() {
        Bundle bundle = new Bundle();
        bundle.putFloat(KEY_TIME_COUNT,timecounter);
        Message msg = handler.obtainMessage();
        msg.setData(bundle);
        handler.sendMessage(msg);
    }
    public void stopTimer(){
        isRunning.set(false);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值