幸运大抽奖。
在ThreadDemoMessage项目中,有两个按钮,单击“开始抽奖”即进入名单滚动环节,单击“大奖揭晓”按钮,名单停止滚动,显示的名字即为中奖的幸运者。
分析:按下按钮“开始抽奖”之后在开启线程之后每隔500ms随机抽取一个名字,然后通过消息机制传递给主线程,在UI界面进行显示。
ThreadDemoMessage项目的MainActivity.java
package com.example.threaddemomessage;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
Button btn_start, btn_ok;
TextView tv_result;
private Thread luckThread;
private Handler mHandler;
private boolean flag=true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//完成对应控件的初始化工作,当需要初始化的控件比较多时,建议将其放于init()方法中,便于理解。
init();
//创建Handler类的实例并重写handleMessage()方法。
mHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
tv_result.setText(msg.obj.toString());
}
};
}
private void init(){
btn_start = (Button) findViewById(R.id.btn_start);
btn_ok= (Button) findViewById(R.id.btn_ok);
tv_result = (TextView) findViewById(R.id.result);
//启动子线程开始抽奖,抽奖结束后销毁子线程。通过按钮“开始抽奖”启动子线程,通过按钮“大奖揭晓”将线程终止。
btn_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (luckThread==null || !luckThread.isAlive()) {
//flag = true;
luckThread = new LuckThread();
luckThread.start();
Log.e("===", "start");
}
}
});
btn_ok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (luckThread != null && luckThread.isAlive()) {
luckThread.interrupt();
luckThread = null;
//flag = false;
Toast.makeText(getApplicationContext(), "大奖已经诞生了!", Toast.LENGTH_LONG).show();
Log.e("===", "end");
}
}
});
}
//定义子线程:在子线程中每过500ms随机抽取一个名字,然后以Message的形式传送到主线程的MessageQueue。
class LuckThread extends Thread{
@Override
public void run() {
super.run();
String[] names={"张彤","王月月","陈晓遇","孙兆玲","马千里"};
try
{
while(!Thread.interrupted())
{
Thread.sleep(500);
Random rand =new Random();
int r=rand.nextInt(names.length);
String luckman=names[r];
Message msg=Message.obtain();
msg.obj=luckman;
mHandler.sendMessage(msg);
Log.e("====",luckman);
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
ThreadDemoMessageByPost项目的MainActivity.java
•
注意,这里没有开子线程,使用的是
handler.postDelayed
()
方法发送
Runnable
消息。
•
由于
Runnable
里面并无耗时操作,
postDelayed
(runnable, 500);
会将
Runnable
消息发送到
MessageQueue
,主线程处理延迟
500
ms
,
Handler
不自己处理
Delay
。
•
注意不要在
post
或
postDelayed
里面写耗时的操作,因为它的
run()
方法工作在主线程,类似于
Message
机制中的
handleMessage
()
方法。
package com.example.threaddemomessage;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
Button btn_start, btn_ok;
TextView tv_result;
private Thread luckThread;
// 声明一个Handler对象
private static Handler handler=new Handler();
private Runnable runnable = new Runnable() {
@Override
public void run() {
String[] names={"张彤","王月月","陈晓遇","孙兆玲","马千里"};
Random rand =new Random();
int r=rand.nextInt(names.length);
String luckman=names[r];
tv_result.setText(luckman);
handler.postDelayed(runnable,500);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
btn_start = (Button) findViewById(R.id.btn_start);
btn_ok = (Button) findViewById(R.id.btn_ok);
tv_result = (TextView) findViewById(R.id.result);
btn_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.postDelayed(runnable, 500);
}
});
btn_ok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.removeCallbacks(runnable);
Toast.makeText(getApplicationContext(), "大奖已经诞生了!", Toast.LENGTH_LONG).show();
}
});
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView android:text="等待抽奖……"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/result" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始抽奖"
android:id="@+id/btn_start"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="大奖揭晓"
android:id="@+id/btn_ok"
/>
</LinearLayout>
res/values/dimens.xml
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="fab_margin">16dp</dimen>
</resources>