1 java层的camera 预览回调onPreviewFrame是在哪个线程调用的?
答案是在调用open camera的这个线程,前提是这个线程要有关联的looper,如果没有,就会在main thread上面。底层在获取到相机原始数据后,会把onPreviewFrame消息送到looper关联的消息队列里。
2 疑问,android_main入口中,里面实现如果不进行消息处理,也就是不调用 source->process(state, source); 为什么会造成app死机?也就是main thread不处理其相关的looer,这会导致相机onpreviewframe不被调用。
android_main是有别于UI主线程的单独线程,由pthread_create创建,测试发现如果不调用source->process(state, source); ,会导致main thread阻塞,调用这个后,mainThread会正常处理消息,就像主线程打开的camera,如果不source->process(state, source),onPreviewFrame是不能被调用的,如果source->process(state, source);,onPreviewFrame仍旧在main Thread调用。好像android_main的线程的looper会优先处理所有事件,他会把属于main thread的事件发放给他。
另外一个奇怪的现象是,android_main中open camera,onpreviewframe仍旧会在main thread的线程里面调用。
相关参考http://www.ikerhurtado.com/android-ndk-native-activity-app-glue-lib-lifecycle-threads
I put some high level notes about the implementation.
The following diagram indicates how the main and background thread work together to create the multi-threaded native activity:
At startup the main thread creates a unidirectional pipe for communication between the main UI thread and the background thread.
When an activity lifecycle or UI event occurs, the main thread simply writes a command to the write end of the pipe. Because the signal is left before actual processing of the events, the main thread can return from the callback function quickly without worrying about the possible long processing.
In the background thread the the true loop implemented in the android_main function will poll for events. Once an event is detected, the function calls the event handler, which reads the exact command from the read end of the pipe and handles it.
The android_native_app_glue library implements all the main thread stuff and part of the background thread stuff for us. We only need to supply the polling loop and the event handler.
The library attaches two event queues for the event loop to be created by us in the background thread, including the activity lifecycle event queue and the input event queue
如果希望onPreviewFrame被正常调用,可以借助 HandlerThread来将回调放到一个单独的线程里面。HanderThread有一个自己的looper,camera投递的onpreviewFrame会被这个线程里面调用,因此还是可以获取到相机数据。