Android子線程中更新UI的4種方法

方法一:用Handlerandroid

一、主線程中定義Handler: 安全

Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0: //完成主界面更新,拿到數據 
                String data = (String)msg.obj; updateWeather(); textView.setText(data); break; default: break; } } }; 

二、子線程發消息,通知Handler完成UI更新: 網絡

private void updateWeather() {

      new Thread(new Runnable(){ @Override public void run() { //耗時操做,完成以後發送消息給Handler,完成UI更新; mHandler.sendEmptyMessage(0); //須要數據傳遞,用下面方法; Message msg =new Message(); msg.obj = "數據";//能夠是基本類型,能夠是對象,能夠是List、map等; mHandler.sendMessage(msg); } }).start(); }

方法一的Handler對象必須定義在主線程中,若是是多個類直接互相調用,就不是很方便,須要傳遞content對象或經過接口調用; 

方法二:用Activity對象的runOnUiThread方法更新 多線程

在子線程中經過runOnUiThread()方法更新UI: 併發

new Thread() {  
            public void run() {  
                //這兒是耗時操做,完成以後更新UI;  
                runOnUiThread(new Runnable(){
@Override public void run() { //更新UI imageView.setImageBitmap(bitmap); } }); } }.start();

  若是在非上下文類中(Activity),能夠經過傳遞上下文實現調用; ide

Activity activity = (Activity) imageView.getContext();  
                activity.runOnUiThread(new Runnable() {  
  
                    @Override  
                    public void run() {  
                        imageView.setImageBitmap(bitmap);  
                    }  
                });

  這種方法使用比較靈活,但若是Thread定義在其餘地方,須要傳遞Activity對象; 

方法三:View.post(Runnable r) post

imageView.post(new Runnable(){ @Override public void run() { imageView.setImageBitmap(bitmap); } });

這種方法更簡單,但須要傳遞要更新的View過去; url

 

方法四:AsyncTaskspa

//UI線程中執行 
new DownloadImageTask().execute( "www.91dota.com" ); private class DownloadImageTask extends AsyncTask { protected String doInBackground( String... url ) { return loadDataFormNetwork( url[0] );//後臺耗時操做 
 } protected void onPostExecute( String result ) { myText.setText( result ); //獲得來自網絡的信息刷新頁面  } }

總結:線程

一、其實上面的四種方式均可歸結於一種方式:handler 用於Android線程之間的通訊。

二、爲何android要求只能在UI線程進行UI操做? 主要仍是爲了不多線程形成的併發的問題。在單線程操做UI是安全的。

相關文章
相關標籤/搜索