Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android多線程及Handler使用

Android多線程及Handler使用

編輯:關於Android編程

當我們需要執行一些耗時操作,比如說發起一條網絡請求時,考慮到網速等其他原因,服務器未必會立刻響應我們的請求,如果不將這類操作放在子線程裡去運行,就會導致主線程被阻塞住,從而影響用戶對軟件的正常使用

開啟子線程

Android多線程編程其實並不比Java多線程編程特珠,基本都是使用相同的語法。比如說,定義一個線程只需要新建一個類繼承自Thread,然後重寫父類的run()方法,並在裡面編寫耗時邏輯即可,如下所示:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //啟動這個線程
        new MyThread().start();
    }
    class MyThread extends Thread{
        @Override
        public void run() {
            super.run();
        }
    }

當然,使用繼承的方式耦合性有點高,更多的時候我們都會選擇使用實現Runnable接口的方式來定義一個線程,如下所示:

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

        MyThread myThread = new MyThread();
        new Thread(myThread).start();
    }
    class MyThread implements Runnable {

        @Override
        public void run() {
            // 處理具體的邏輯
        }
    }

可以看到,Thread的構造函數接收一個Runnable參數,而我們new出的MyThread正是一個實現了Runnable接口的對象,所以可以直接將它傳入到Thread的構造函數裡。接著調用Thread的start()方法,run()方法中的代碼就會在子線程當中運行了。
當然,如果你不想專門再定義一個類去實現Runnable接口,也可以使用匿名類的方式,這種寫法更為常見,如下所示:

new Thread(new Runnable() {

    @Override
    public void run() {
        // 處理具體的邏輯
    }

}).start();

以上幾種線程的使用方式相信你都不會感到陌生,因為在Java中創建和啟動線程也是使用同樣的方式。

更新UI之Handler

Handler的主要作用是在工作線程中發送消息和在UI線程中獲取、處理消息。
一個Handler允許發送和處理Message或者Runnable對象

Post:Post允許把一個Runnable對象入隊到消息隊列中。它的方法有:
post(Runnable r) postAtTime(Runnable,long) -在特定的時間執行 postDelayed(Runnable,long) -延遲delayMills秒執行

注意 對於Post方式而言,它其中Runnable對象的run()方法的代碼,均執行在UI線程上,裡面不能有耗時操作

sendMessage: sendMessage允許把一個包含消息數據的Message對象壓入到消息隊列中。它的方法有:

sendEmptyMessage(int) -發送一個空的Message對象 sendMessageAtTime(Message,long) -在UI線程取到消息後,延遲執行 sendMessageDelayed(Message,long)。-空的Message對象,在UI線程取到消息後,延遲執行

這方面的更多資料請看http://www.cnblogs.com/shirley-1019/p/3557800.html

簡單的延時進度示例

這裡用到了一個handler的post方式
對於Handler的Post方式來說,它會傳遞一個Runnable對象到消息隊列中

ProgressBar bar = (ProgressBar) findViewById(R.id.bar);
.....
public void click2(View view) {

        final Handler handler =new Handler();

        Runnable runnable =new Runnable() {
            @Override
            public void run() {
                pro =bar.getProgress()+5;
                bar.setProgress(pro);
                handler.postDelayed(this,100);
            }
        };
        handler.postDelayed(runnable,1000);
    }

當然你也可以這樣寫更加簡便

ProgressBar bar = (ProgressBar) findViewById(R.id.bar);
.....
public void click2(View view) {

   final Handler handler =new Handler();

   handler.postDelayed(new Runnable() {
            @Override
            public void run() {
               pro =bar.getProgress()+5;
               bar.setProgress(pro);
               handler.postDelayed(this,100);
            }
        }, 1000);
   }

handleMessage處理消息

sendMessage允許把一個包含消息數據的Message對象壓入到消息隊列中

public class HandlerTest extends Activity {

    public static final int UPDATE_TEXT = 1;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case UPDATE_TEXT:
                    // 在這裡可以進行UI操作
                    //比如 text.setText(msg.getData().getString("time"));
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        new Thread(new Runnable() {
            @Override
            public void run() {

                Message message = new Message();
                message.what = UPDATE_TEXT;
                handler.sendMessage(message); // 將Message對象發送出去

                /*String time=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date());
                Message message = Message.obtain();
                Bundle bundle=new Bundle();
                bundle.putString("time",time);
                message.setData(bundle);//bundle傳值,耗時,效率低
                handler.sendMessage(message);//發送message信息
                message.what=1;//標志是哪個線程傳數據
                //message有四個傳值方法,
                //兩個傳int整型數據的方法message.arg1,message.arg2
                //一個傳對象數據的方法message.obj
                //一個bandle傳值方法*/
            }
        }).start();
    }
}

這裡寫圖片描述


在子線程更新UI簡便方法

因為runOnUiThread工作在主線程裡

  runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                      //更新UI操作  
                    }
                });
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved