一,Thread
public class MainActivity extends Activity
{
TextView time;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
time = findViewById(R.id.time);
syncTask.start();
}
Thread syncTask = new Thread() {
int i = 0;
public void run() {
while (true){
i+=1;
time.setText("时间:"+i);
try{
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
}
}
};
}
二,Runable
public class MainActivity extends Activity
{
TextView time;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
time = findViewById(R.id.time);
syncTask.start();
}
Thread syncTask = new Thread(new Runnable() {
int i = 0;
public void run() {
while (true){
i+=1;
time.setText("时间:"+i);
try{
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
}
}
});
}
三,Handler
有些需求需要子线程不断的从一个消息队列中取出消息,并进行处理,处理完毕以后继续取出下一个处理。对于这个需求我们可以使用第一种方式,实现一个Thread对象,并创建一个消息队列,在Thread对象的run方法中不断的从消息队列中取出消息进行处理。多以该线程的这些特点有点像一个Looper线程,我们可复用Handler机制提供的消息队列MessageQueue,而无需自己重新创建。
HandlerThread的内部实现机制很简单,在创建新的线程后,使该线程成为一个Looper线程,让该线程不断的从MessageQueue取出消息并处理。
子线程运行自己数据并发送给主线程
Thread syncTask = new Thread(new Runnable() {
int i = 0;
public void run() {
while (true){
i+=1;
bundle.putString("time","时间:"+i);
Message message = Message.obtain();
message.setData(bundle);
message.what = 0x11;
handler.sendMessage(message);
try{
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
}
}
});
主线程接收子线程消息并更新UI
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
time = findViewById(R.id.time);
syncTask.start();
handler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0x11) {
Bundle bundle2 = msg.getData();
time.setText("时间:"+bundle2.getString("time"));
}
}
};
}
四,AsyncTask
这是我们最经常使用的一种异步方式,在前面的两种多线程方式中,如果在子线程中进行了耗时的处理操作(如:网络请求、读写数据库等),当操作完毕后,我们需要更新UI上的显示状态,但在Android开发中我们是不能在子线程中更新UI界面的,所以还得在子线程中发送一个通知到主线程,让主线程去更新UI。这样的操作流程有些复杂,且都是重复性的工作。所以Android sdk中为我们抽象出AsyncTask这个类。
public class MainActivity extends Activity
{
TextView time;
MyTask syncTask = new MyTask();
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
time = findViewById(R.id.time);
syncTask.execute();
}
private class MyTask extends AsyncTask<String, Integer, String>{
int i = 0;
protected String doInBackground(String... strings) {
while (true){
i++;
try {
publishProgress();
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
}
}
protected void onProgressUpdate(Integer... progresses) {
time.setText("时间:"+i);
}
}
}
- 直接使用Thread实现方式,这种方式简单,但不是很优雅。适合数量很少(偶尔一两次)的异步任务,但要处理的异步任务很多的话,使用该方式会导致创建大量的线程,这会影响用户交互。
- HandlerThread,这种方式适合子线程有序的执行异步操作,异步任务的执行一个接着一个。
- AsyncTask, 通常用于耗时的异步处理,且时效性要求不是非常高的那种异步操作。如果时效性要求非常高的操作,不建议使用这个方式,因为AsyncTask的默认实现是有内部排队机制,且是整个应用的AsyncTask的任务进行排队,所以不能保证异步任务能很快的被执行。