Trong bài này Tui sẽ đưa ra 1 ví dụ cuối cùng về cách xử lý đa tiến trình, bài này tương đối phức tạp, bạn phải tập trung làm đi làm lại để hiểu thêm.

Giao diện chính của chương trình như sau:

async5– Mô tả sơ sơ: Khi nhấn nút Start, chương trình sẽ vẽ bên màn hình bên trái điện thoại là danh sách các số ngẫu nhiên, sau khi vẽ xong (hoặc là đồng thời) chương trình sẽ vẽ danh sách các số là số nguyên tố nằm bên màn hình trái vào màn hình bên phải.

– Bạn tạo project như hình dưới đây:

async6

– Giao diện hơi phức tạp 1 xíu, ở đây Tui chia màn hình ra làm hai, bạn xem XML Resource:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
<LinearLayout xmlns:android="http://splashurl.com/ot4qqf8
 android:id="@+id/LinearLayout1"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context=".MainActivity" >
<LinearLayout
 android:layout_width="match_parent"
 android:layout_height="wrap_content" >
<Button
 android:id="@+id/btnstart"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Start:" />
<EditText
 android:id="@+id/editnumber"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_weight="1"
 android:ems="10"
 android:hint="enter number of here"
 android:inputType="number" >
<requestFocus />
 </EditText>
 </LinearLayout>
<TableLayout
 android:layout_width="fill_parent"
 android:layout_height="wrap_content" >
<TableRow
 android:id="@+id/tableRow1"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content" >
<TextView
 android:id="@+id/textView1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_weight="1"
 android:background="#008000"
 android:gravity="center"
 android:text="Random Number:"
 android:textColor="#FFFFFF" />
<TextView
 android:id="@+id/textView2"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_weight="1"
 android:background="#8000FF"
 android:gravity="center"
 android:text="List Prime:"
 android:textColor="#FFFFFF" />
 </TableRow>
<TableRow
 android:id="@+id/tableRow2"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" >
<ScrollView
 android:id="@+id/scrollView1"
 android:layout_width="wrap_content"
 android:layout_weight="1"
 android:layout_height="wrap_content" >
<LinearLayout
 android:id="@+id/llrandomnumber"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical" >
 </LinearLayout>
 </ScrollView>
<ScrollView
 android:id="@+id/scrollView2"
 android:layout_width="wrap_content"
 android:layout_weight="1"
 android:layout_height="wrap_content" >
<LinearLayout
 android:id="@+id/llprimenumber"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical" >
</LinearLayout>
 </ScrollView>
 </TableRow>
 </TableLayout>
</LinearLayout>

– Xử lý coding, bạn xem MyAsyncTask: 

Class này Tui kế thừa từ: AsyncTask<Integer, Integer, ArrayList<Integer>>

Integer ở đối số 1: Được truyền vào khi ta thực thi tiến trình.

Integer ở đối số 2: Được truyền vào để tiến hành cập nhật giao diện trong hàm publishProgress

ArrayList<Integer>: Kết quả trả về sau khi thực hiện xong tiến trình.

Việc đưa control động cũng tương tự như các bài trước.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package tranduythanh.com;
import java.util.ArrayList;
import java.util.Random;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.SystemClock;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
public class MyAsyncTask extends
 AsyncTask<Integer, Integer, ArrayList<Integer>>
{
 private LinearLayout llrandom,llprime;
 private Random rd=new Random();
 private Activity context;
 public MyAsyncTask(Activity context)
 {
 //lấy các control trong MainThread
 this.llrandom=(LinearLayout)
 context.findViewById(R.id.llrandomnumber);
 this.llprime=(LinearLayout)
 context.findViewById(R.id.llprimenumber);;
 this.context=context;
 }
 //Begin - can use UI thread here
 protected void onPreExecute() {
 super.onPreExecute();
 Toast.makeText(context, "Start here",
 Toast.LENGTH_SHORT).show();
 //khi bắt đầu thực thi tiến trình thì tiến hành xóa toàn bộ control bên trong
 this.llrandom.removeAllViews();
 this.llprime.removeAllViews();
 }
 protected ArrayList<Integer> doInBackground(Integer... params) {
 int step=1;
 ArrayList<Integer>list=new ArrayList<Integer>();
 //vòng lặp chạy hết n số button truyền vào
 int n=params[0];
 while(isCancelled()==false && step<=n)
 {
 step++;
 SystemClock.sleep(100);
 //lấy số ngẫu nhiên
 int x=rd.nextInt(100)+1;
 //gọi cập nhật giao diện
 publishProgress(x);
 //nếu là số nguyên tố thì lưu vào danh sách
 if(isPrime(x))
 list.add(x);
 }
 //trả về danh sách số nguyên tố
 return list;
 }
 @Override
 protected void onProgressUpdate(Integer... values) {
 super.onProgressUpdate(values);
 //lấy giá trị truyền vào trong doinbackground
 Integer item=values[0];
 //tạo Button với Text có giá trị là số ngẫu nhiên
 Button btn=new Button(context);
 btn.setWidth(100);
 btn.setHeight(30);
 btn.setText(item+"");
 //đưa button lên view bên trái màn hình
 this.llrandom.addView(btn);
 }
 public void doRawPrime(int x)
 {
 //hàm vẽ các Button là chứac các số nguyên tố
 Button btn=new Button(context);
 btn.setWidth(100);
 btn.setHeight(30);
 btn.setText(x+"");
 //đưa Button vào view bên phải màn hình
 this.llprime.addView(btn);
 }
 //hàm kiểm tra số nguyên tố
 public boolean isPrime(int x)
 {
 if(x<2)return false;
 for(int i=2;i<=Math.sqrt(x);i++){
 if(x%i==0)return false;}
 return true;
 }
 @Override
 protected void onPostExecute(ArrayList<Integer> result) {
 super.onPostExecute(result);
 //sau khi tiến trình kết thúc thì hàm này sẽ được thực thi
 //lấy về danh sách các số nguyên tố
 final ArrayList<Integer>list=result;
 //tiến hành dùng Handler class để thực hiện
 final Handler handler=new Handler();
 Thread th=new Thread(new Runnable() {
 public void run() {
 //lặp để vẽ các Button là số nguyên tố
 for(int i=0;i<list.size();i++){
 final int x=list.get(i);
 SystemClock.sleep(100);
 handler.post(new Runnable() {
 public void run() {
 doRawPrime(x);}
 });
 }
 handler.post(new Runnable() {
 public void run() {
 Toast.makeText(context, "Finish",
 Toast.LENGTH_SHORT).show();
 }
 });
 }
 });
 th.start();
 }}//end MyAsyncTask

Mục đích của bài này là Tui muốn nói rằng chúng ta có thể kết hợp các kỹ thuật xử lý đa tiến trình với nhau.

Ở đây Tui có 1 câu hỏi nhỏ là, nếu trong hàm onPostExecute Tui muốn sử dụng lại MyAsyncTask thì viết coding như thế nào là hớp lý (ý của tui là chỉ sử dụng 1 class MyAsyncTask, nhưng ta có thể thông qua nó để tạo nhiều tiến trình khác nhau với những chức năng khác nhau). Bạn hãy suy nghĩ và làm thử.

Tiếp tục xem MainActivity:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package tranduythanh.com;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity {
 Button btnstart;
 MyAsyncTask task;
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 btnstart=(Button) findViewById(R.id.btnstart);
 btnstart.setOnClickListener(new
 View.OnClickListener() {
 public void onClick(View arg0) {
 doStart();
 }
 });
 }
 public void doStart()
 {
 String s=((EditText)
 this.findViewById(R.id.editnumber))
 .getText().toString();
 //lấy số lượng từ EditText
 int n=Integer.parseInt(s);
 task=new MyAsyncTask(this);
 task.execute(n);
 }
}

– Bài này có 1 chút phức tạp, bạn cố gắng đọc hiểu.

– Bạn có thể tải coding mẫu ở đây: http://www.mediafire.com/download/1m270fb1zpdw628/LearnMultiThreading_AsyncTask_Handler.rar

– Bài kết tiếp Tui sẽ trình bày về BroadCastReceiver và cách xử lý khi có tin nhắn gửi tới, bạn có thể ứng dụng nó để viết phần mềm Xử Lý Tin Nhắn Rác. Bạn chú ý theo dõi.

– Chúc các bạn thành công.

Nguồn: http://duythanhcse.wordpress.com/category/l%E1%BA%ADp-trinh-android/