我开发了一个非常基本的相机应用程序,到目前为止它只包含相机预览和一个拍摄照片然后保存的按钮。我现在想知道为什么我会发出一个警告,我的应用程序可能正在做很多工作的主线程(它跳过35帧)。我在我的UI线程上所做的所有操作都可以在onCreate()
:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fullScreencall();
setContentView(R.layout.activity_capture);
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera);
preview.addView(mPreview, 0);
mButtonCapture = (Button) findViewById(R.id.btnCapturePhoto);
mButtonCapture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ImageSaverThread ist = new ImageSaverThread(mCamera);
ist.start();
}
});
}
对我而言,这似乎不是那么多工作,我找不到任何可以分成另一个线程的东西。拍摄照片并保存已经在一个帖子中完成了。
知道我在这里缺少什么吗?
修改
ImageSaverThread.java
public class ImageSaverThread extends Thread {
private Camera mCamera;
public static final int MEDIA_TYPE_IMAGE = 1;
public ImageSaverThread(Camera camera){
mCamera = camera;
}
public void run(){
PictureCallback mPicture = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
Log.d("FAIL", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("FAIL", "Error accessing file: " + e.getMessage());
}
}
};
mCamera.takePicture(null, null, mPicture);
}
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(String.valueOf(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)));
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
}
答案 0 :(得分:1)
getCameraInstance
可能是一个漫长的过程。您可能需要在另一个线程上运行它。文档建议这样做。
请参阅此处发布的答案,了解更多相关信息:Android camera: Threads? Which should do what
编辑:
当有人点击该按钮时,您可能会遇到其他问题。在实例化ImageSaverThread
对象之前,不会创建静态方法。检查文件等可能需要一些时间作为静态方法,因此您可能希望将其更改为非静态方法。
更多信息,请参阅此帖子。 Static Initialization Blocks
此外,这是一个“警告” - 而不是“错误”。 35帧不多,帧数将根据可用内存,平台和其他可能正在运行的优先级线程而有所不同。