我们在Android开发过程中,经常会遇到这个问题,因为:Android要求只能在UI线程中更新UI,要想在其他线程中更新UI,只能通过异步方式来实现。
实现方式有多种,我这边常用的有以下两种:
1、使用Handler消息传递机制。(这个非常经典)
2、使用AsyncTask异步任务。
1、使用Handler消息传递机制,代码如下:
import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.widget.TextView; public class MainActivity extends Activity { private TextView tv; //创建handler Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { if(msg.what==0) //如果消息是刚才发送的标识 { tv.setText("接收到handler发过来的消息进行UI更新"); } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView) findViewById(R.id.tv); new MyThread().start(); } class MyThread extends Thread { @Override public void run() { //延迟两秒更新 try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } handler.sendEmptyMessage(0); //工作线程的handler发送消息 } } }
2、使用AsyncTask异步任务,代码如下:
注意:异步刷新UI的操作在onPostExecute()方法中进行处理。(包括视频下载等功能可以用异步任务的方式实现,在doInBackgroud()方法里执行下载操作,完成后,在onPostExecute()里执行完成后的UI界面更新)
import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends Activity { private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView) findViewById(R.id.tv); new MyAsyncTask().execute(); } class MyAsyncTask extends AsyncTask<String, String, String> { @Override protected String doInBackground(String... params) { try { Thread.sleep(2000); //睡2秒 } catch (InterruptedException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String result) { // TODO Auto-generated method stub tv.setText("异步更新TextView内容"); } } }