我只是好奇是否有时候我应该选择Executor一个HandlerThread.是否有时候一个优于另一个,或者我真的应该坚持HandlerThread?就我而言,我正在侦听一个ServerSocketfor连接,并在一个单独的线程上处理每个请求Executor.尽管我给出了一个具体的例子,但我真的只是在寻找一个比另一个更合适的案例.但是,我欢迎对我的设计发表评论.
我想从GUI线程设置一个HandlerThread.然后一段时间后,当在GUI上单击一个按钮时,它会运行callHello(),然后将消息发送到驻留在非GUI线程上的HelloLogger对象,该线程异步记录"Hello World".我已经尝试过很多东西,有些是无限期阻塞,有些是从不接收消息等等.下面的代码或多或少都和我一样接近,请有人修改它吗?
public class HandlerThreadExample {
private MyHandlerThread mMyHandlerThread;
private Looper mLooper;
private Handler mHandler;
public HandlerThreadExample(){
mMyHandlerThread = new MyHandlerThread();
mMyHandlerThread.start();
mLooper = mMyHandlerThread.getLooper();
}
public void callHello() {
mHandler.sendEmptyMessage(1);
}
private class MyHandlerThread extends HandlerThread {
private HelloLogger mHelloLogger;
private Handler mHandler;
public MyHandlerThread() {
super("The MyHandlerThread thread", HandlerThread.NORM_PRIORITY);
}
public void run (){
mHelloLogger = new HelloLogger();
mHandler = new Handler(getLooper()){
public void handleMessage(Message msg){
mHelloLogger.logHello();
}
};
super.run();
}
}
private class HelloLogger {
public HelloLogger …Run Code Online (Sandbox Code Playgroud) multithreading android android-handler android-handlerthread
我正在为Android应用程序制作自定义相机,如"SnapChat",但相机预览在诸如(Moto g第二代,一个+一个)但很少(三星s3,三星s4)等少数设备上延伸.我使用以下参考 全屏相机显示/预览不保持纵横比 - 图像歪斜,拉伸以适应屏幕.但这对我100%没有帮助.我在分享屏幕.
三星摩托G第二代的拉伸图像是.

没有拉伸的三星S3图像是Above
private void setPreviewLayout() {
if (null == mCamera) {
return;
}
Camera.Parameters parameters = null;
Camera.Size size = null;
try {
int screenWidth = (int) getResources().getDisplayMetrics().widthPixels;
int screenHeight = (int) getResources().getDisplayMetrics().heightPixels;
parameters = mCamera.getParameters();
size = getOptimalPreviewSize(mCamera.getParameters().getSupportedPreviewSizes(), screenWidth, screenHeight);
if (size != null) {
parameters.setPreviewSize(size.width, size.height);
}
parameters.setPictureSize(screenHeight, screenWidth);
;
mCamera.setParameters(parameters);
if (on && currentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
} else {
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
}
parameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
parameters.setExposureCompensation(0);
parameters.setPictureFormat(ImageFormat.JPEG);
parameters.setJpegQuality(100);
List<String> focusModes = parameters.getSupportedFocusModes(); …Run Code Online (Sandbox Code Playgroud) 我想写一个活动:
是否有适用于每台设备的完整示例?链接到一个简单的开源应用程序拍照将是理想的答案.
我的研究到目前为止:
这是一个常见的场景,有很多问题和教程.
主要有两种方法:
方法1本来是完美的,但问题是每个设备上的意图实现不同. 在某些设备上它运作良好.但是,在某些设备上,您可以拍照,但它永远不会返回到您的应用.在某些设备上,启动意图时没有任何反应.通常它还将图像保存到SD卡,并且需要存在SD卡.每个设备上的用户交互也不同.
方法2的问题是稳定性.我尝试了一些例子,但我设法阻止相机在某些设备上工作(直到重启)并完全冻结另一台设备.在另一台设备上捕捉工作,但预览保持黑色.
我会使用ZXing作为示例应用程序(我经常使用它),但它只使用预览(取景器),并且不拍任何照片.我还发现,在某些设备上,ZXing在光照条件改变时没有自动调整白平衡,而原生相机应用程序正确地做到了(不确定是否可以修复).
更新:
有一段时间我直接使用了相机API.这提供了更多控制(自定义UI等),但我不建议任何人.我会在90%的设备上工作,但是每次都会发布一个新的设备,但是会遇到不同的问题.
我遇到的一些问题:
所以一般来说,除非没有别的办法,否则我不建议去这条路线.两年后,我通过自定义代码转储并切换回基于Intent的方法.从那时起,我的麻烦就少了很多.我过去在基于意图的方法中遇到的问题可能只是我自己的无能.
如果你真的需要走这条路,我听说如果你只支持Android 4.0+的设备会更容易.
一旦调用Camera.takePicture(),我的预览将停止更新,如文档中所述.检测图像捕获过程的最佳方法是什么,并调用startPreview()使其再次开始更新?
根据文档,调用不能放在传递给takePicture的任何回调中,因为它们应该在我调用之前返回.
我目前最好的猜测是创建一个Handler并从JPEG回调中发布一个延迟的Runnable(或者是最后一个定义的回调函数).
一个线程在它自己的构造函数中调用this.start()是否合法?如果是这样,这会导致什么样的潜在问题?我知道对象不会完全初始化,直到构造函数运行完成,但除此之外还有其他问题吗?
我在Galaxy s6边缘设备上有以下例外
java.lang.RuntimeException: Camera is being used after Camera.release() was called
at android.hardware.Camera.setPreviewSurface(Native Method)
at android.hardware.Camera.setPreviewDisplay(Camera.java:702)
at com.forsale.forsale.view.uicomponent.qrcode.CameraPreview.surfaceCreated(CameraPreview.java:59)
at android.view.SurfaceView.updateWindow(SurfaceView.java:712)
at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:316)
at android.view.View.dispatchWindowVisibilityChanged(View.java:10434)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1328)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1328)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1328)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1328)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1328)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1750)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1437)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7397)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:920)
at android.view.Choreographer.doCallbacks(Choreographer.java:695)
at android.view.Choreographer.doFrame(Choreographer.java:631)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:906)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7224)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private PreviewCallback …Run Code Online (Sandbox Code Playgroud) 我正在尝试通过Camera的PreviewCall返回(onPreviewFrame)使用MediaCodec对每秒30帧的视频进行编码.我编码的视频总是播放得非常快(这是不可取的).所以,我试图通过设置一个int frameCount变量来检查进入我相机预览的帧数,以记住它的计数.我期待的是每秒30帧,因为我将相机的预览设置为30 fps预览(如下所示).我回来的结果是不一样的.我调用onPreviewFrame回调10秒钟,我得到的帧数量只有大约100帧.这很糟糕,因为我期待300帧.我的相机参数设置正确吗?这是Android的Camera预览回拨的限制吗?如果这是对Android相机预览回调的限制,那么还有其他相机回调能够以每秒30帧的速度返回相机的图像数据(nv21,yuv,yv12)吗?
感谢您阅读并花时间去帮忙.我将不胜感激任何评论和意见.
以下是使用Camera的onPreviewFrame编码视频的示例:
http://www.youtube.com/watch?v=I1Eg2bvrHLM&feature=youtu.be
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewFormat(ImageFormat.NV21);
parameters.setPictureSize(previewWidth,previewHeight);
parameters.setPreviewSize(previewWidth, previewHeight);
// parameters.setPreviewFpsRange(30000,30000);
parameters.setPreviewFrameRate(30);
mCamera.setParameters(parameters);
mCamera.setPreviewCallback(previewCallback);
mCamera.setPreviewDisplay(holder);
Run Code Online (Sandbox Code Playgroud) 尝试从Android ICS中的本机代码开始使用相机:大多数手册都是指startPreview()方法.但是浏览AOSP代码我发现了' startRecording() '方法<Camera.h>.这里说它来自接口ICameraRecordingProxy" 允许录音机在录音期间接收视频帧 "
所以问题是 - 在性能方面,'startRecording'方法比'startPreview'更有效吗?
进入本机代码的唯一目标是性能,Java'Camera'太慢,OpenCV也不提供所需的FPS级别.
编辑:目标平台是:API级别= 17,设备Allwinner A31开发板,1280x720x30FPS.任务是从相机捕获帧,修改它们,编码(H264)并存储到SD卡.纯java MediaRecorder用1280x720x30写入mp4文件.不需要在屏幕上显示实时预览.
本机模式下的OpenCV-demo1提供1920x1080x2(在java模式下相同).具有空PreviewCallback最大FPS的简单Java方法是15.
先感谢您..
正如在处理相机的Android文档中所指出的,建议使用单独的线程来打开相机.
好吧,我这样做但确实遇到了一些困难:
对于我的相机对象,我使用的是全局实例变量.现在,当我启动我的应用程序时,我创建了一个单独的线程,onResume()并在该线程中对该相机对象执行所有初始化.
后来当我离开应用程序时,我将相机放入onPause().这一切都很好.
但问题是:当我做了一些压力测试和切换非常快之间onResume()并onPause()(通过点击多任务按钮过快),我的应用程序崩溃.原因是有一个Method called after release().
这是有道理的,因为可能会释放相机,onPause()但同时线程尚未完成其初始化.因此,线程尝试对已经释放的相机对象进行调用.
现在,我该怎么做才能解决这个问题?也许不使用全球相机对象?或者我该如何使这个线程安全?