Android中更新UI的三种方式

Android中更新UI的三种方式

Android中更新UI的三种方式:

1.在工作线程中更新UI

2.使用AsyncTask

3.使用Handler

本博客的界面用的同一个xml

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

android:id="@+id/hello_text"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Hello World!" />

android:id="@+id/change_btn"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Change"

android:textAllCaps="false"/>

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);

}

});

}

});

}

}

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{

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);

}

}

}

效果截图:

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;

}

}

}

}

相关推荐

民政部关停13家非法社会组织网站
oa.house365.com

民政部关停13家非法社会组织网站

📅 07-05 👁️ 932
阴阳师召唤阵怎么用-现世召唤阵大全
oa.house365.com

阴阳师召唤阵怎么用-现世召唤阵大全

📅 07-29 👁️ 8100
今天是《仙剑奇侠传》发售29周年
oa.house365.com

今天是《仙剑奇侠传》发售29周年

📅 08-29 👁️ 9101