java中随机数的健壮性,Handler的用法

首先撇清一个概念:Android的单线程设计是指每个应用程序的UI线程(主线程)是单线程的,即和用户交互的界面是单线程的。但是,很显然,用户界面如果采用多线程处理效率会更高,Android为什么将UI线程限制为单线程呢?这是为了避免并发编程的复杂性,也是提高Android应用的健壮性的有效途径。

但是,主线程是单线程的,并不等于Android不支持多线程,比如两个Android应用程序之间的通讯。

Android中的Handler提供了线程之间通讯的简便手段,如下图所示:

8ff0ab79e991ee4455df3dbbed998a4b.png

Android的主线程(即UI线程)内部实现了消息队列机制,即一个主线程会自动创建一个消息队列(显然也只有一个消息队列),同时创建一个读取消息队列的Looper对象。主线程的所有用户交互都通过消息队列和Looper对象来实现:当有新的消息进入消息队列时,Looper会及时读取消息并调用相应的处理逻辑(更新用户界面)。

当其他线程希望更新用户界面时,可以通过Handler提供的sendMessage方法在消息队列中放入一个消息(Message对象,可以携带大量信息),这样Looper即可以及时获取该消息,并调用Handler相应的handleMessage方法处理该消息,这样就实现了线程之间的通讯。由此可以看出,Handler在线程通讯中起到了一个枢纽作用:Handler即负责和消息队列打交道,也负责处理相应的消息,其他线程通过Handler和主线程通讯,就可以不需要考虑和主线程的竞争和同步问题,极大的简化了线程的使用。

下面的示例代码演示了一个每隔1秒显示一条消息在主界面:

public class MainActivity extends Activity {

private TextView label;

private static int UPDATE = 1;

private Handler handler = new Handler() {

@Override

public void handleMessage(Message msg) {

if (msg.what == 1) {

label.setText(String.valueOf(msg.obj));

super.handleMessage(msg);

}

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

label = (TextView) findViewById(R.id.label);

new Thread() {

@Override

public void run() {

for (int i = 0; i < 100; i++) {

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

Message msg = new Message();

msg.what = UPDATE;

msg.obj = "当前循环变量:" + i;

handler.sendMessage(msg);

}

}

}.start();

}

}

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

publicclassMainActivityextendsActivity{

privateTextViewlabel;

privatestaticintUPDATE=1;

privateHandlerhandler=newHandler(){

@Override

publicvoidhandleMessage(Messagemsg){

if(msg.what==1){

label.setText(String.valueOf(msg.obj));

super.handleMessage(msg);

}

}

};

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

label=(TextView)findViewById(R.id.label);

newThread(){

@Override

publicvoidrun(){

for(inti=0;i<100;i++){

try{

Thread.sleep(1000);

}catch(InterruptedExceptione){

// TODO Auto-generated catch block

e.printStackTrace();

}

Messagemsg=newMessage();

msg.what=UPDATE;

msg.obj="当前循环变量:"+i;

handler.sendMessage(msg);

}

}

}.start();

}

}

在上面的例子中,所谓的其他线程其实主线程的子线程,下面一个例子则演示了完全不同的两个组件通过Handler实现的交互:一个Service每隔1秒产生一个随机数,然后在主线程显示出来:

ServiceDemo.java文件:

public class ServiceDemo extends Service {

@Override

public IBinder onBind(Intent arg0) {

// TODO Auto-generated method stub

return null;

}

private Thread workThread;

@Override

public void onCreate() {

super.onCreate();

Toast.makeText(this, "(1) onCreate()",

Toast.LENGTH_LONG).show();

workThread = new Thread(null,backgroudWork,"WorkThread");

}

@Override

public void onStart(Intent intent, int startId) {

super.onStart(intent, startId);

Toast.makeText(this, "(2) onStart()",

Toast.LENGTH_SHORT).show();

if (!workThread.isAlive()){

workThread.start();

}

}

@Override

public void onDestroy() {

super.onDestroy();

Toast.makeText(this, "(3) onDestroy()",

Toast.LENGTH_SHORT).show();

workThread.interrupt();

}

private Runnable backgroudWork = new Runnable(){

@Override

public void run() {

try {

while(!Thread.interrupted()){

double randomDouble = Math.random();

MainActivity.updateGUI(randomDouble);

Thread.sleep(1000);

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

};

}

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

publicclassServiceDemoextendsService{

@Override

publicIBinderonBind(Intentarg0){

// TODO Auto-generated method stub

returnnull;

}

privateThreadworkThread;

@Override

publicvoidonCreate(){

super.onCreate();

Toast.makeText(this,"(1) onCreate()",

Toast.LENGTH_LONG).show();

workThread=newThread(null,backgroudWork,"WorkThread");

}

@Override

publicvoidonStart(Intentintent,intstartId){

super.onStart(intent,startId);

Toast.makeText(this,"(2) onStart()",

Toast.LENGTH_SHORT).show();

if(!workThread.isAlive()){

workThread.start();

}

}

@Override

publicvoidonDestroy(){

super.onDestroy();

Toast.makeText(this,"(3) onDestroy()",

Toast.LENGTH_SHORT).show();

workThread.interrupt();

}

privateRunnablebackgroudWork=newRunnable(){

@Override

publicvoidrun(){

try{

while(!Thread.interrupted()){

doublerandomDouble=Math.random();

MainActivity.updateGUI(randomDouble);

Thread.sleep(1000);

}

}catch(InterruptedExceptione){

e.printStackTrace();

}

}

};

}

MainActivity.java文件:

public class MainActivity extends Activity {

private static TextView label;

private static int UPDATE = 1;

protected static Handler handler = new Handler() {

@Override

public void handleMessage(Message msg) {

if (msg.what == 1) {

label.setText(String.valueOf(msg.obj));

super.handleMessage(msg);

}

}

};

public static void updateGUI(double doubleRadom){

Message msg = new Message();

msg.what = UPDATE;

msg.obj = "当前随机数:" + doubleRadom;

handler.sendMessage(msg);

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

label = (TextView) findViewById(R.id.label);

final Intent serviceIntent = new Intent(this, ServiceDemo.class);

startService(serviceIntent);

}

}

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

publicclassMainActivityextendsActivity{

privatestaticTextViewlabel;

privatestaticintUPDATE=1;

protectedstaticHandlerhandler=newHandler(){

@Override

publicvoidhandleMessage(Messagemsg){

if(msg.what==1){

label.setText(String.valueOf(msg.obj));

super.handleMessage(msg);

}

}

};

publicstaticvoidupdateGUI(doubledoubleRadom){

Messagemsg=newMessage();

msg.what=UPDATE;

msg.obj="当前随机数:"+doubleRadom;

handler.sendMessage(msg);

}

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

label=(TextView)findViewById(R.id.label);

finalIntentserviceIntent=newIntent(this,ServiceDemo.class);

startService(serviceIntent);

}

}

可以看出,为了实现在两个组件间的通讯,主要的变化是:

将Handler对象定义为static类型的,便于在其他组件访问handler

在主线程中实现一个静态的updateGUI方法,以便通过调用handler.sendMessage添加一个消息到消息队列中

在Service的线程中,调用主线程的updateGUI并传入适当的参数

Handler和消息循环机制的设计很巧妙,在WEB应用和企业级应用中是否可以借鉴呢?

d4c39bd54dfbfe627dbd9fe226767b2c.png

0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值