Andorid的多线程操作/UI

介绍在Android中任何开启多线程

Andorid的多线程操作/UI

本篇已Java为主要语言

线程

  1. Thread
  2. AsyncTask

Thread的使用

Thread子线程运行
  1. 创建一个类,继承Thread,并且重写run方法(如下)
1
2
3
4
5
6
class MyThread extends Thread(){
@Override
protected void run(){
//TODO
}
}

只需要在run方法中写耗时操作即可

  1. 使用: MyThread.start();
  2. 更改写法,继承Runnable
1
2
3
4
5
6
class MyThread extends Runnable(){
@Overrid
protected void run(){
//TODO
}
}

更改了写法,使用方法也需要改变,

1
2
MyThread thread = new MyThread();
thread.start();
Thread子线程通知UI更改
  1. 首先在子线程中是不运行进行UI操作,想要进行UI操作,只能在主线程中进行操作。
  2. 那么,在子线程中想要更改UI,就只能通过Handler来进行UI操作
  • 先介绍一下Handler
    1. Message :消息体,可携带一些信息,在不同线程之间进行传递数据
    2. Handler :消息 发送/处理 者,可通过Handler.sendMessage()来发送数据,也可以在handlerMesage中处理数据
    3. MessageQueue :消息队列,里面存放等待处理的消息
    4. Looper : MessageQueue的管家 用来开启一个无限循环,不停的查看MessageQueue中是否还有信息,如果存在,则取出给Handler进行处理。
  1. 代码展示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class MainActivity extends AppCompatActivity {
private TextView textView;
private Handler handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
textView.setText((String) msg.obj);
//在handleMessage中是属于主线程
//就可以从Message中取出传递的消息,赋值到TextView上去
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.title);
new MyThread().start();
//开启线程
}

public class MyThread extends Thread {
@Override
public void run() {
//在子线程中想要更改UI,那么就只能通知Handler来更改UI
Message message = new Message();
message.obj = "这是一个消息";
handler.sendMessage(message);
//这里向Handler传递了一个Message,Message里包含了一段文字
}
}
}

AsyncTask

  1. 介绍:相比 Thread来说,AsyncTask将方便很多,不需要复杂的通知Handler进行UI操作,全部都可以在AsyncTask中完成
  2. 使用起来也很简单,创建一个类继承AsyncTask并传递3个参数即可,下面将介绍AsyncTask的3个需要重写的方法
    • onPreExecute:此方法处于主线程,可进行一些UI初始化操作,比如说初始化进度条
    • doInBackground:此方法处于子线程,用于进行一些耗时操作
    • onProgressUpdate:此方法处于主线程,可进行UI操作,并且如果设置了返回值,将会不停的在doInBackground运行时返回结果
  3. 下面将以下载功能并且更新进度条为例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class AsyncTaskDome extends AppCompatActivity {
private ProgressDialog progressDialog;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_async_task_dome);
progressDialog = new ProgressDialog(this);
new Download().execute("下载地址");
}

public class Download extends AsyncTask<String, Integer, Boolean> {

@Override
protected void onPreExecute() {
progressDialog.show();
//初始化进度条
}

@Override
protected Boolean doInBackground(String... strings) {
//这里假装在进行下载
Uri uri = Uri.parse(strings[0]);
return true;
}

@Override
protected void onProgressUpdate(Integer... integers) {
//这里对进度条进行更新进度
progressDialog.setMessage(String.valueOf(integers[0]));
}
}
}

这样子就完成了在子线程中更新UI