線程及異步操作
大體上闡述了異步處理的重要性,以及什麼時候應該用異步處理等等巴拉巴拉......
重點:
1:
AsyncTask類的介紹及例子......
通過繼承AsyncTask類並實現其定義的事件方法,管理後台操作。
很方便的是AsyncTask類已經為異步操作創建好了一個簡單的接口,我們只需實現這個接口就可以很快捷的實現異步操作。
並且在最新的幾個SDK中,它能夠通過若干個物理內核和一個內部線程池來同時管理多個任務。
包括:
onPreExecute()方法在後台操作開始前運行在UI線程上
doInBackground()方法運行在後台並處理後台操作
從該方法中調用publishProgress()方法能夠周期性的通知UI線程有關後台操作的進度
當其( doInBackground()方法 )調用publishProgress()方法時
onProgressUpdate()方法就會在UI線程中運行,通過不同的參數來傳遞不同的信息
一旦後台操作完成,就會自動在UI線程中調用onPostExrcute()方法,AsyncTask類能夠以後台的方式處理操作,不會阻塞UI線程。
啟動方法有2種:
1.實例化所創建的AsyncTask子類,調用execute()方法,啟動異步操作。
2.實例化所創建的AsyncTask子類,調用executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR, Integer... )方法,啟動異步操作。
區別:API L11+的設備中,前者( execute() ) 任務可以”平行“的被執行,在多核處理器設備上,該方法能有效地提高任務的完成速度,並隱性的提高應用程序的效率和流暢性。後者( executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR, Integer... ) )則保證了同時執行若干個任務,每個任務相互獨立。
注:如果不想同時執行多個任務,可以調用executeOnExecutor( AsyncTask.SERIAL_EXECUTOR )方法,但是只有再API L14+中才能確認是線性的。
實例:
1 package com.example.asynctask;
2
3 import android.os.AsyncTask;
4 import android.os.Bundle;
5 import android.os.SystemClock;
6 import android.app.Activity;
7 import android.widget.TextView;
8
9 public class SimpleAsyncTask extends Activity {
10
11 @Override
12 protected void onCreate(Bundle savedInstanceState) {
13 super.onCreate(savedInstanceState);
14 setContentView(R.layout.activity_main);
15
16 CountingTask tsk = new CountingTask();
17 tsk.execute();
18
19 }
20
21 private class CountingTask extends AsyncTask<Void, Integer, Integer> {
22
23 CountingTask() {
24 }
25
26 @Override
27 protected Integer doInBackground(Void... unused) {
28
29 int i = 0;
30 while (i < 100) {
31
32 SystemClock.sleep(100);
33 i++;
34
35 if (i % 5 == 0) {
36
37 // 每5%進度更新一次UI
38 publishProgress(i);
39 }
40 }
41
42 return i;
43 }
44
45 protected void onProgressUpdate(Integer... progress) {
46
47 TextView tv = (TextView) findViewById(R.id.text);
48 tv.setText(progress[0] + " % Complete! ");
49 }
50
51 protected void onPostExecute(Integer result) {
52
53 TextView tv = (TextView) findViewById(R.id.text);
54 tv.setText("Count Complete ! Count to " + result.toString());
55 }
56 }
57 }
復制代碼
復制代碼
1 package com.example.asynctask;
2
3 import android.app.Activity;
4 import android.os.AsyncTask;
5 import android.os.Bundle;
6 import android.os.SystemClock;
7 import android.widget.TextView;
8
9 public class SimpleMultiCoreAsyncTask extends Activity {
10
11 @Override
12 protected void onCreate(Bundle savedInstanceState) {
13 super.onCreate(savedInstanceState);
14 setContentView(R.layout.activity_simple_multi_core_async_task);
15
16 CountingTask tsk = new CountingTask();
17 tsk.executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR, R.id.tv_AsyncTask_1 );
18
19 startParallelTask( R.id.tv_AsyncTask_2 );
20 startParallelTask( R.id.tv_AsyncTask_3 );
21 startParallelTask( R.id.tv_AsyncTask_4 );
22 startParallelTask( R.id.tv_AsyncTask_5 );
23 startParallelTask( R.id.tv_AsyncTask_6 );
24
25 //注意,貌似只能第一時間同時啟動前5個,完成後才會啟動第6個......
26 }
27
28 private void startParallelTask( int _id ) {
29
30 CountingTask tsk = new CountingTask();
31 tsk.executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR, _id );
32 }
33
34 private class CountingTask extends AsyncTask<Integer, Integer, Integer> {
35
36 private int _counterID;
37
38 CountingTask() {
39 }
40
41 @Override
42 protected Integer doInBackground(Integer... _id) {
43
44 _counterID = _id[ 0 ];
45 int i = 0;
46
47 while (i < 100) {
48
49 SystemClock.sleep(100);
50 i++;
51
52 if (i % 5 == 0) {
53
54 // 每5%進度更新一次UI
55 publishProgress(i);
56 }
57 }
58
59 return i;
60 }
61
62 protected void onProgressUpdate(Integer... progress) {
63
64 TextView tv = (TextView) findViewById( _counterID );
65 tv.setText(progress[0] + " % Complete! ");
66 }
67
68 protected void onPostExecute(Integer result) {
69
70 TextView tv = (TextView) findViewById( _counterID );
71 tv.setText("Count Complete ! Count to " + result.toString());
72 }
73 }
74 }
復制代碼
------------------------------------------------我是分割線--------------------------------------------------------------
2:Thread類
比起上面的( AsyncTask ) ,其( Thread )類導入已有的代碼更為簡便直接
對於一個擁有獨立線程的Activity類能夠管理線程的生命周期,一般就會包括一個Handler類型的變量,Thread類被實例化啟動時,Handler的post()方法就會被用於與主UI線程的通信,當然也可以使用Activity類中的runOnThread()方法或是View類中的post()和postDelayed()方法來與主UI線程通信。
實例:
1 package com.example.asynctask;
2
3 import android.os.Bundle;
4 import android.os.SystemClock;
5 import android.app.Activity;
6 import android.view.Menu;
7 import android.widget.TextView;
8
9 public class SimpleThread extends Activity {
10
11 @Override
12 protected void onCreate(Bundle savedInstanceState) {
13 super.onCreate(savedInstanceState);
14 setContentView(R.layout.activity_simple_thread);
15
16 final TextView tv_thread = ( TextView ) findViewById( R.id.tv_thread );
17
18 new Thread( new Runnable() {
19
20 @Override
21 public void run() {
22
23 int i = 0;
24
25 while ( i < 100 ) {
26
27 SystemClock.sleep( 250 );
28 i++;
29
30 final int curCount = i;
31
32 if( curCount % 5 == 0 ) {
33
34 tv_thread.post( new Runnable() {
35
36 @Override
37 public void run() {
38
39 tv_thread.setText( curCount + " % Complete! " );
40 }
41 });
42 }
43 }
44
45 tv_thread.post( new Runnable() {
46
47 @Override
48 public void run() {
49
50 tv_thread.setText( "Count Complete!" );
51 }
52 });
53 }
54 }).start();
55 }
56 }