Android Multi-threads Programming for Intel IA

See original blog post: Android 多线程编程 on Intel China ISN

Android application development can be supported with multi-threaded programming, which provide convenience for developers to fully utilize the system resource and provide means of designing complicated UI and time consuming operation. It also enhances the user experience of Android users. Multi-threads for Android has no too much difference than for Java. The only change may be that it probably can not directly utilize CANVAS to  modify screen element. Certainly Android provides developers with surfaceview class to change screen using Canvas in Multi-threaded programming and bring convenience for designing UI and Game development. So it is very important that developers need to learn how to use  multi-threaded programming, which plays important role as part of Android programming.

There are many ways of achieving  threading, the most popular way is :

start();

run();

sleep();

stop();

destroy();

join();

suspend();

resume();

yield();
wait();
notify();

Threading start must use start(); Threading can use run(); Threading sleep can use sleep () etc.. The first three methods are most popular usage. Generally speaking, these three methods can satisfy the need for most threading usage. When run() end, the thread automatically  end life. Although stop() , or destroy()  can be used to stop thread, but are not recommended as stop() can  turn into abnormal, and destroy() can turn into force termination. and will release the lock. The solution is to set a status signal in RUN to wait the thread to terminate automatically.  Here we use volatile boolean bThreadRun. For suspend (), resume() and yield(), they are rarely used due to the possibility of dead lock. So in most situation, developers will use wait() and notify() to replace them.

Here is a multi-thread example. I will use a thread to calculate  a variable and update the new window title. The main source codes are like this: Use Eclipse to create a project, Use Activity to add onStart, onPause, and onStop etc. Activity is the most popular class that we use, and is also a core Class for Android. It is used to  administer and display a screen for an app, and Android developer should be very familiar with it.  Activity operation is following the sequence: onCreate,onStart,onStop,onPause,onResume, onRestart,onDestroy,onRestoreInstanceState,onSaveInstanceState. The popular execution sequence is onCreate,onStart,onResume. When windows is not  at the top level, onPause,onstop are executed, if it is on the top, then onRestart,onResume will be executed.  The loop will continue until onDestroy. If you want to save window, just reload onSaveInstanceState,and reload onRestoreInstanceState when enter。Here are the example that multi-thread is created in onStart using Activity method:

01.MyThread myThread = new MyThread();
02. myThread.start();

Add MyThread code below:

01.public class MyThread extends Thread {
02. // Claim character variable
03. public MyThread() {
04. }
05.
06. @Override
07. public void start() {
08. super.start();
09. }
10.
11. // main working method of thread
12. @Override
13. public void run() {
14. while (true) {
15. try {
16. sleep(5000);
17. if (c > ((1 << 31) - 1)) {
18. c = 0;
19. } else {
20. c++;
21. }
22. Message message = new Message();
23. message.what = 1;
24. mHandler.sendMessage(message);
25. } catch (InterruptedException ex) {
26. }
27. }
28. }
29.
30. }

Method of realize updatetitle:

01.public void updateTitle() {
02. setTitle("test thread " + c);
03. }

Here updatetitle  is not used to directly update new window, instead, handler is used. The reason is that the direct usage of updatetitle  is not safe, and may cause threading restart and other issues. Android introduced Handler as a special class, and use it as a bi-direction bridge between Runnable and Activity. So we can only send Message in method run, but in Handler, we use different Message to execute different tasks, and add handler for program:

01.private Handler mHandler = new Handler() {
02. public void handleMessage(Message msg) {
03. switch (msg.what) {
04. case 1:
05. updateTitle();
06. break;
07. }
08. };
09. };

The final version of completed source codes are as below,threading is used to process data and display data on window:

01.package com.test;
02.
03.import android.app.Activity;
04.import android.os.Bundle;
05.import java.lang.Thread;
06.import android.os.Message;
07.import android.os.Handler;
08.import android.graphics.Color;
09.
10.public class TestThreadActivity extends Activity {
11. int c = Color.BLUE;
12. MyThread myThread;
13. volatile boolean bThreadRun = false;
14.
15. /** Called when the activity is first created. */
16. @Override
17. public void onCreate(Bundle savedInstanceState) {
18. super.onCreate(savedInstanceState);
19. setContentView(R.layout.main);
20. }
21.
22. @Override
23. protected void onRestoreInstanceState(android.os.Bundle savedInstanceState) {
24. super.onRestoreInstanceState(savedInstanceState);
25. }
26.
27. @Override
28. protected void onSaveInstanceState(android.os.Bundle outState) {
29. super.onSaveInstanceState(outState);
30. }
31.
32. @Override
33. protected void onStart() {
34. super.onStart();
35. myThread = new MyThread();
36. myThread.start();
37. bThreadRun = true;
38. }
39.
40. @Override
41. protected void onRestart() {
42. super.onRestart();
43. }
44.
45. @Override
46. protected void onResume() {
47. super.onResume();
48. }
49.
50. @Override
51. protected void onPause() {
52. super.onPause();
53. bThreadRun = false;
54. // myThread.stop();
55. }
56.
57. @Override
58. protected void onStop() {
59. super.onStop();
60. onPause();
61. }
62.
63. @Override
64. protected void onDestroy() {
65. super.onDestroy();
66. // myThread.destroy();
67. }
68.
69. private Handler mHandler = new Handler() {
70. public void handleMessage(Message msg) {
71. switch (msg.what) {
72. case 1:
73. updateTitle();
74. break;
75. }
76. };
77. };
78.
79. public void updateTitle() {
80. setTitle("test thread " + c);
81. setTitleColor(c);
82. }
83.
84. public class MyThread extends Thread {
85. // Claim character variable
86. public MyThread() {
87. }
88.
89. @Override
90. public void start() {
91. super.start();
92. }
93.
94. // The main method of work of threading
95. @Override
96. public void run() {
97. while (bThreadRun) {
98. try {
99. sleep(100);
100. if (c > ((1 << 16) - 1)) {
101. c = 0;
102. } else {
103. c += 100;
104. }
105. Message message = new Message();
106. message.what = 1;
107. mHandler.sendMessage(message);
108. } catch (InterruptedException ex) {
109. }
110. }
111. }
112.
113. }
114.
115.}

Another popular way of threading is to compile Runnable interface. Here we do some modification to the source codes to use threading to realize the redraw of main window. The complete source codes are as below:

01.package com.test;
02.
03.import android.app.Activity;
04.import android.content.Context;
05.import android.os.Bundle;
06.import java.lang.Thread;
07.import android.view.View;
08.import android.graphics.Canvas;
09.import android.graphics.Color;
10.import android.graphics.Paint;
11.import android.graphics.Paint.Style;
12.import android.graphics.Rect;
13.
14.public class TestThreadActivity extends Activity {
15. int c = Color.BLUE;
16. MyThread myThread;
17. volatile boolean bThreadRun = false;
18. MyView mv;
19.
20. /** Called when the activity is first created. */
21. @Override
22. public void onCreate(Bundle savedInstanceState) {
23. super.onCreate(savedInstanceState);
24. // setContentView(R.layout.main);
25. mv = new MyView(this);
26. setContentView(mv);
27. }
28.
29. public class MyView extends View {
30. MyView(Context context) {
31. super(context);
32. }
33.
34. @Override
35. protected void onDraw(Canvas canvas) {
36. // TODO Auto-generated method stub
37. super.onDraw(canvas);
38.
39. // Fist define  a paint
40. Paint paint = new Paint();
41.
42. // draw rectangular area -solid filled rectangular
43. // configure color
44. paint.setColor(c);
45. // Configure style and fill
46. paint.setStyle(Style.FILL);
47. //Draw a rectangular
48. canvas.drawRect(new Rect(0, 0, getWidth(), getHeight()), paint);
49. }
50.
51. }
52.
53. @Override
54. protected void onRestoreInstanceState(android.os.Bundle savedInstanceState) {
55. super.onRestoreInstanceState(savedInstanceState);
56. }
57.
58. @Override
59. protected void onSaveInstanceState(android.os.Bundle outState) {
60. super.onSaveInstanceState(outState);
61. }
62.
63. @Override
64. protected void onStart() {
65. super.onStart();
66. //myThread = new MyThread();
67. //myThread.start();
68. new Thread (new MyThread()).start();
69. bThreadRun = true;
70. }
71.
72. @Override
73. protected void onRestart() {
74. super.onRestart();
75. }
76.
77. @Override
78. protected void onResume() {
79. super.onResume();
80. }
81.
82. @Override
83. protected void onPause() {
84. super.onPause();
85. bThreadRun = false;
86. // myThread.stop();
87. }
88.
89. @Override
90. protected void onStop() {
91. super.onStop();
92. onPause();
93. }
94.
95. @Override
96. protected void onDestroy() {
97. super.onDestroy();
98. // myThread.destroy();
99. }
100.
101. public class MyThread implements Runnable{
102. // the main method of work of threading
103. @Override
104. public void run() {
105. while (bThreadRun) {
106. try {
107. Thread.sleep(500);
108. if (c > ((1 << 31) - 1)) {
109. c = 0;
110. } else {
111. c += 100;
112. }
113. mv.postInvalidate();
114. } catch(InterruptedException e){
115. }
116. }
117. }
118.
119. }
120.
121.}

 
For more complete information about compiler optimizations, see our Optimization Notice.
Categories: