android入门:zxing学习笔记(五)
2013-05-12 13:38
260 查看
莫道君行早,更有早行人。
Barcode Scanner不只是上面两篇说的这么简单,还有其他处理,如闪光灯,放大处理,最优的预览尺寸等等。这些不影响对代码的理解,知道camera的使用后,开始看看Barcode Scanner是如何高效的进行识别处理的。在android文件夹下,就有一个thread类:DecodeThread,两个handler类:CaptureActivityHandler和DecodeHandler。在没有认真看两个类时,一直以为这两个handler是理所当然的方式,以为自己就知道了。后面发现不是这么简单,尤其是DecodeThread的实现是android
中工作线程的经典实现。
在Barcode Scanner中,有着繁多的消息传送,处理的消息的handler也有两个。如何将消息传送到指定的handler中去,从代码上看挺清晰的,将message和指定的handler绑定。前面提到过,在android中有主线程和工作线程之分。Activity这类的main thread,还有自己创建的work thread,如果要更新UI,则需要再main thread中进行处理,可以通过handler来实现消息传递,将消息送到main thread的消息队列去。
Barcode Scanner中有两个Thread 和 两个handler,在这四个类中通过加入这样的语句判断他们thread中得关系:
最后运行的结果:
由此可见,这两个handler都分别属于他们的thread。但在创建这两个handler时,有很大的差别。CaptureActivityHandler的创建只是简简单单的new了,没有其他辅助。这就是main activity在创建时,系统默认为它创建一个looper,负责管理该线程的消息循环,取送消息等,不需要额外指定。但对于自己创建的Thread,系统默认是没有为其创建looper的,需要自己为它创建消息循环。
先看下DecodeThread的代码 : 去掉了跟理解线程不相关的代码。
前面定义了一个CountDownLatch类型变量,该变量为一个倒计数用的锁。用法挺简单,如代码中,先new CountDownLatch(1),计数值为1, handlerInitLatch.countDown(), 开始倒数。handlerInitLatch.await() 若计数值没有变为0,则一直阻塞。直到计数值为0后,才return handler,因此在调用getHandler时不会返回null的handler。
在创建DecodeThread线程的handler时,首先在线程中调用Looper.prepare()来创建消息队列,再创建附于该线程的handler对象,最后调用Looper.loop()进入消息循环,这个这个loop()循环不会立马返回,需要自己主动调用Looper.myLooper().quit()才会返回。这就是自己创建一个工作线程,为其分配一个消息队列,消息循环的简单迅速办法。
前面说到camera的自动聚焦,只是隔断时间定期的不停向CaptureActivityHandler发送自动聚焦请求,这就是一个消息传送:
这样创建了消息,隔断时间发送。
关于Android的消息处理机制,这里有篇更好的文章,请点这里。还有这一篇介绍looper的。这两篇说的更透彻,实用。这还发现一篇巨作。
Barcode Scanner不只是上面两篇说的这么简单,还有其他处理,如闪光灯,放大处理,最优的预览尺寸等等。这些不影响对代码的理解,知道camera的使用后,开始看看Barcode Scanner是如何高效的进行识别处理的。在android文件夹下,就有一个thread类:DecodeThread,两个handler类:CaptureActivityHandler和DecodeHandler。在没有认真看两个类时,一直以为这两个handler是理所当然的方式,以为自己就知道了。后面发现不是这么简单,尤其是DecodeThread的实现是android
中工作线程的经典实现。
在Barcode Scanner中,有着繁多的消息传送,处理的消息的handler也有两个。如何将消息传送到指定的handler中去,从代码上看挺清晰的,将message和指定的handler绑定。前面提到过,在android中有主线程和工作线程之分。Activity这类的main thread,还有自己创建的work thread,如果要更新UI,则需要再main thread中进行处理,可以通过handler来实现消息传递,将消息送到main thread的消息队列去。
Barcode Scanner中有两个Thread 和 两个handler,在这四个类中通过加入这样的语句判断他们thread中得关系:
1 System.out.println(TAG + "The worker thread id = " + Thread.currentThread().getId()); //判断线程ID
最后运行的结果:
1 01-12 02:41:12.594: I/System.out(655): CaptureActivity The main thread id = 1 2 01-12 02:41:14.605: I/System.out(655): CaptureActivityHandler The handler thread id = 1 3 01-12 02:41:12.946: I/System.out(655): DecodeThread The worker thread id = 13 4 01-12 02:41:13.094: I/System.out(655): DecodeHandler The handler thread id = 13
由此可见,这两个handler都分别属于他们的thread。但在创建这两个handler时,有很大的差别。CaptureActivityHandler的创建只是简简单单的new了,没有其他辅助。这就是main activity在创建时,系统默认为它创建一个looper,负责管理该线程的消息循环,取送消息等,不需要额外指定。但对于自己创建的Thread,系统默认是没有为其创建looper的,需要自己为它创建消息循环。
先看下DecodeThread的代码 : 去掉了跟理解线程不相关的代码。
1 final class DecodeThread extends Thread { 2 public static String TAG = DecodeThread.class.getSimpleName(); 3 private final CaptureActivity activity; 4 private Handler handler; 5 private final CountDownLatch handlerInitLatch;//到计数的锁 6 DecodeThread(CaptureActivity activity, 7 Vector<BarcodeFormat> decodeFormats, 8 String characterSet, 9 ResultPointCallback resultPointCallback) { 10 11 this.activity = activity; 12 handlerInitLatch = new CountDownLatch(1);//从1开始到计数 13 14 } 15 16 Handler getHandler() { 17 try { 18 handlerInitLatch.await();//阻塞先等handler被初始化了才能返回结果。改计数锁即等countdown-->0。 19 } catch (InterruptedException ie) { 20 // continue? 21 } 22 return handler; 23 } 24 25 @Override 26 public void run() { 27 Looper.prepare(); 28 handler = new DecodeHandler(activity, hints); 29 handlerInitLatch.countDown();//启动到计数,countdown-1 变成0; 30 System.out.println(TAG + "The worker thread id = " + Thread.currentThread().getId()); //判断线程ID 31 Looper.loop(); 32 }
前面定义了一个CountDownLatch类型变量,该变量为一个倒计数用的锁。用法挺简单,如代码中,先new CountDownLatch(1),计数值为1, handlerInitLatch.countDown(), 开始倒数。handlerInitLatch.await() 若计数值没有变为0,则一直阻塞。直到计数值为0后,才return handler,因此在调用getHandler时不会返回null的handler。
在创建DecodeThread线程的handler时,首先在线程中调用Looper.prepare()来创建消息队列,再创建附于该线程的handler对象,最后调用Looper.loop()进入消息循环,这个这个loop()循环不会立马返回,需要自己主动调用Looper.myLooper().quit()才会返回。这就是自己创建一个工作线程,为其分配一个消息队列,消息循环的简单迅速办法。
前面说到camera的自动聚焦,只是隔断时间定期的不停向CaptureActivityHandler发送自动聚焦请求,这就是一个消息传送:
1 Message message = autoFocusHandler.obtainMessage(autoFocusMessage, success); 2 autoFocusHandler.sendMessageDelayed(message, AUTOFOCUS_INTERVAL_MS);
这样创建了消息,隔断时间发送。
关于Android的消息处理机制,这里有篇更好的文章,请点这里。还有这一篇介绍looper的。这两篇说的更透彻,实用。这还发现一篇巨作。
相关文章推荐
- android入门:zxing学习笔记(四)
- android入门:zxing学习笔记(一)
- android入门:zxing学习笔记(三)
- android入门:zxing学习笔记(六)
- android入门:zxing学习笔记(四)
- android入门:zxing学习笔记(二) 照相的边框
- android入门:zxing学习笔记
- android入门:zxing学习笔记(一)
- android入门:zxing学习笔记(四)
- android入门:zxing学习笔记(二)
- android入门:zxing学习笔记(五)
- android入门:zxing学习笔记(四)
- android入门:zxing学习笔记(一)
- android入门:zxing学习笔记(二)
- android入门:zxing学习笔记(四)
- android入门:zxing学习笔记(二)
- Android入门:zxing学习笔记(一)
- android入门:zxing学习笔记(六)
- android入门:zxing学习笔记(三)
- 小猪的Android入门之路 Day 8 part 2