四种异步更新UI的方法
Android要求只能在UI线程中更新UI,要想在其他线程中更新UI,大致有四种方式:
1.使用Handler消息传递机制(推荐)
2.使用AsyncTask异步任务(推荐)
3.使用runOnUiThread(action)方法;
4.使用View的post(Runnabel r)方法;
5.使用handler的post
一.Handler:
public class MainActivity extends Activity { TextView tip; Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { tip.setText("handl更新"); if( msg.what == 0 ){ tip.setText("handl更新"); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tip = (TextView)findViewById(R.id.tip); } protected void myClick(View v){ if( v.getId() == R.id.btn ){ new Thread(new Runnable() { @Override public void run() { try{ Thread.sleep(1000); }catch (InterruptedException e){ e.printStackTrace(); } Message msg = handler.obtainMessage(); msg.what = 0; handler.sendMessage(msg); } }).start(); } } }
二.AsyncTask:
简单示例:
public class MainActivity extends Activity { TextView tip; MyAsyncTask myAsyncTask; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tip = (TextView)findViewById(R.id.tip); myAsyncTask = new MyAsyncTask(); myAsyncTask.execute(); } class MyAsyncTask extends AsyncTask<Void,String, Boolean>{ // 非UI线程中,独立线程 @Override protected Boolean doInBackground(Void... params) { try{ Thread.sleep(1000*5); }catch (InterruptedException e){ e.printStackTrace(); } return true; } // UI线程 @Override protected void onPostExecute(Boolean aBoolean) { tip.setText("AsyncTask更新了"); } }; }
更详细的用法:http://www.cnblogs.com/itfenqing/p/6748261.html
三.runOnUiThread
runOnUiThread(Runnable)把更新ui的代码创建在Runnable中,然后在需要更新ui时,把这个Runnable对象传给Activity.runOnUiThread(Runnable)。 这样Runnable对像就能在ui程序中被调用。如果当前线程是UI线程,那么行动是立即执行。如果当前线程不是UI线程,操作是发布到事件队列的UI线程
public class MainActivity extends Activity { TextView tip; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tip = (TextView)findViewById(R.id.tip); new Thread(new Runnable() { @Override public void run() { try{ Thread.sleep(10*1000); }catch (InterruptedException e){ e.printStackTrace(); } runOnUiThread(new Runnable() { @Override public void run() { tip.setText("runOnUiThread"); } }); } }).start(); } }
四.使用View的post方法:
public class MainActivity extends Activity { TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView)findViewById(R.id.tip); new Thread(new Runnable() { @Override public void run() { try{ Thread.sleep(10000); }catch (InterruptedException e){ e.printStackTrace(); } tv.post(new Runnable() { @Override public void run() { tv.setText("view post"); } }); } }).start(); } }
五.Handler.post
public class MainActivity extends Activity { TextView tv; Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView)findViewById(R.id.tip); handler = new Handler(); new Thread(new Runnable() { @Override public void run() { try{ Thread.sleep(10000); }catch (InterruptedException e){ e.printStackTrace(); } handler.post(new Runnable() { @Override public void run() { tv.setText("home"); } }); } }).start(); } }
可以在子线程里更新的控件及方法:
ProgressBar
ListView 的notifyDataSetChanged()