1. 程式人生 > 其它 >Android中更新UI的三種方式

Android中更新UI的三種方式

置頂 Android_蔥 2019-04-07 14:57:40 4695 收藏 18
分類專欄: Android 文章標籤: Android UI 執行緒 AsyncTask Handler
版權

Android
專欄收錄該內容
7 篇文章0 訂閱
訂閱專欄
Android中更新UI的三種方式:
1.在工作執行緒中更新UI
2.使用AsyncTask
3.使用Handler

本部落格的介面用的同一個xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:id="@+id/hello_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />

<Button
android:id="@+id/change_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change"
android:textAllCaps="false"/>

</LinearLayout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1.在工作執行緒中更新
在上一篇部落格中,我寫到工作執行緒中不能對UI控制元件進行操作,但最後提到了(Android系統提供了一些工具用於在工作執行緒中更新主執行緒)
(1)使用View的postInvalidate()方法重新整理頁面
(2)使用Activity的runOnUiThread()方法更新UI
(3)使用View的post()和postDelayed()方法更新UI

public class MainActivity extends AppCompatActivity {

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

final TextView tv = (TextView) findViewById(R.id.hello_text);
Button bt = (Button) findViewById(R.id.change_btn);

final ExecutorService mThreadPool = Executors.newCachedThreadPool();
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mThreadPool.execute(new Runnable() {
@Override
public void run() {
//重新整理介面
// tv.postInvalidate();

//使用Activity的runOnUiThread()方法更新UI
// MainActivity.this.runOnUiThread(new Runnable() {
// @Override
// public void run() {
// tv.setText("OH,I am Fine!!!");
// }
// });

//使用View的post()方法更新UI
// tv.post(new Runnable() {
// @Override
// public void run() {
// tv.setText("Hi,Fresh By Post");
// }
// });

//使用View的postDelayed()方法更新UI
tv.postDelayed(new Runnable() {
@Override
public void run() {
tv.setText("Hi,Fresh By postDelayed :");
}
},1000);
}
});
}
});
}
}
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
2.使用AsyncTask
AsyncTask是Android給我們提供的一種輕量級的非同步任務類
我們做一個點選按鈕後,demo會進行10s的倒計時
我們重寫了doInBackground()後,剩下5個回撥方法,他們也是AsyncTask中的生命週期方法,我們在相應的方法中進行初始化,賦值等操作。(下面的程式碼中有詳細的備註)

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

Button bt = (Button) findViewById(R.id.change_btn);

final ExecutorService mThreadPool = Executors.newCachedThreadPool();
bt.setOnClickListener(new View.OnClickListener() {
MyAsyncTask myAsyncTask;
@Override
public void onClick(View v) {
myAsyncTask = new MyAsyncTask();
myAsyncTask.execute(Long.valueOf("10"));
}
});
}

class MyAsyncTask extends AsyncTask<Object,String,String>{

TextView tv;

@Override
protected void onPreExecute() {
tv = (TextView) findViewById(R.id.hello_text);

tv.setText("倒計時開始!");
}

/**
* doInBackground()方法是必須重寫的一個方法
* 唯一的一個執行在工作執行緒中的方法
* 用來執行在工作執行緒中要執行的任務
*/
@SuppressLint("WrongThread")
@Override
protected String doInBackground(Object... objects) {
if (objects.length == 1 && objects[0] instanceof Long){
Long inputTime = (Long) objects[0];
for (;inputTime > 0;inputTime--){
publishProgress(inputTime + "s"); //傳給onProgressUpdate()的引數
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}else{
//這裡用到了上面的執行緒中更新UI的方法,不是AsyncTask更新UI的方法
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
tv.setText("倒計時失敗");
}
});
cancel(true);
}
return null;
}

/**
* onProgressUpdate()方法是執行在主執行緒中的方法
* 所以我們在這裡可以直接對UI進行更新
*
* 我們下面獲取的values是上面publishProgress傳的引數
* (本demo中只有一個String型別的引數)
*/
@Override
protected void onProgressUpdate(String... values) {
tv.setText(values[0]);
}

/**
* onPostExecute()方法是doInBackground()方法執行完畢後執行的方法
*/
@Override
protected void onPostExecute(String s) {
tv.setText("倒計時完畢");
}

/**
* 取消時的回撥方法
*/
@Override
protected void onCancelled(String s) {
super.onCancelled(s);
}
}
}
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
效果截圖:
3.使用Handler更新UI
Handler是Android訊息機制的上層介面。Handler是專門用來線上程之間傳遞訊息的工具類,主要用於UI介面的更新,訊息的傳遞與處理。
Handler傳送訊息的兩種方法:
1.send系列方法:用於傳送一個包含資料的Message物件,並在handleMessage(Message message)方法中處理。(下面demo使用的方法)
2.post系列的方法:用於傳送一個Runnable物件,並在MessageQueue收到訊息時執行。

public class MainActivity extends AppCompatActivity {

private static final int CHANGE = 1;
private TextView tv;

private final MyHandle handle = new MyHandle();

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

Button bt = (Button) findViewById(R.id.change_btn);
tv = (TextView) findViewById(R.id.hello_text);

bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
Message ms = new Message();
ms.what = CHANGE;
handle.sendMessage(ms);
}
}).start();
}
});
}

class MyHandle extends Handler{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case CHANGE:
tv.setText("hello, Changed by Handle!!!");
break;
default:
break;
}
}
}
}
————————————————
版權宣告:本文為CSDN博主「Android_蔥」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/weixin_39936201/article/details/89063607

https://blog.csdn.net/weixin_39936201/article/details/89063607