Android:線程(Thread,Runable,Handler,AsyncTask)

一,Thread

public class MainActivity extends Activity
{
    TextView time;
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        time = findViewById(R.id.time);
        syncTask.start();
    }
    Thread syncTask = new Thread() {
        int i = 0;
        public void run() {
            while (true){
                i+=1;
                time.setText("時間:"+i);
                try{
                    Thread.sleep(1000);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    };
}

二,Runable

public class MainActivity extends Activity
{
    TextView time;
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        time = findViewById(R.id.time);
        syncTask.start();
    }
    Thread syncTask = new Thread(new Runnable() {
        int i = 0;
        public void run() {
            while (true){
                i+=1;
                time.setText("時間:"+i);
                try{
                    Thread.sleep(1000);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    });
}

三,Handler

        有些需求需要子線程不斷的從一個消息隊列中取出消息,並進行處理,處理完畢以後繼續取出下一個處理。對於這個需求我們可以使用第一種方式,實現一個Thread對象,並創建一個消息隊列,在Thread對象的run方法中不斷的從消息隊列中取出消息進行處理。多以該線程的這些特點有點像一個Looper線程,我們可複用Handler機制提供的消息隊列MessageQueue,而無需自己重新創建。
        HandlerThread的內部實現機制很簡單,在創建新的線程後,使該線程成爲一個Looper線程,讓該線程不斷的從MessageQueue取出消息並處理。

子線程運行自己數據併發送給主線程

Thread syncTask = new Thread(new Runnable() {
        int i = 0;
        public void run() {
            while (true){
                i+=1;
                bundle.putString("time","時間:"+i);
                Message message = Message.obtain();
                message.setData(bundle);
                message.what = 0x11;
                handler.sendMessage(message);
                try{
                    Thread.sleep(1000);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
});

主線程接收子線程消息並更新UI

protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        time = findViewById(R.id.time);
        syncTask.start();
        handler = new Handler() {
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.what == 0x11) {
                    Bundle bundle2 = msg.getData();
                    time.setText("時間:"+bundle2.getString("time"));
                }
            }
        };
}

四,AsyncTask

這是我們最經常使用的一種異步方式,在前面的兩種多線程方式中,如果在子線程中進行了耗時的處理操作(如:網絡請求、讀寫數據庫等),當操作完畢後,我們需要更新UI上的顯示狀態,但在Android開發中我們是不能在子線程中更新UI界面的,所以還得在子線程中發送一個通知到主線程,讓主線程去更新UI。這樣的操作流程有些複雜,且都是重複性的工作。所以Android sdk中爲我們抽象出AsyncTask這個類。

public class MainActivity extends Activity
{
    TextView time;
    MyTask syncTask = new MyTask();
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        time = findViewById(R.id.time);
        syncTask.execute();

    }
    private class MyTask extends AsyncTask<String, Integer, String>{
        int i = 0;
        protected String doInBackground(String... strings) {
            while (true){
                i++;
                try {
                    publishProgress();
                    Thread.sleep(1000);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
        protected void onProgressUpdate(Integer... progresses) {
            time.setText("時間:"+i);
        }
    }
}
  • 直接使用Thread實現方式,這種方式簡單,但不是很優雅。適合數量很少(偶爾一兩次)的異步任務,但要處理的異步任務很多的話,使用該方式會導致創建大量的線程,這會影響用戶交互。
  • HandlerThread,這種方式適合子線程有序的執行異步操作,異步任務的執行一個接着一個。
  • AsyncTask, 通常用於耗時的異步處理,且時效性要求不是非常高的那種異步操作。如果時效性要求非常高的操作,不建議使用這個方式,因爲AsyncTask的默認實現是有內部排隊機制,且是整個應用的AsyncTask的任務進行排隊,所以不能保證異步任務能很快的被執行。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章