0
我正在android studio中製作一個自定義攝像頭。如果我退出該應用程序,它會在返回時崩潰。我知道問題在於activity的生命週期,logcat指出我在cameraPreview.java文件中有`mCamera.setPreviewDisplay(surfaceHolder)'的行。我已經看到其他類似的帖子,但我仍然不知道如何解決它。任何幫助表示讚賞。定製安卓攝像頭上的java.lang.NullPointerException
homePage.java
import android.Manifest;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.FrameLayout;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import android.hardware.Camera;
public class homePage extends AppCompatActivity {
private static final int CAMERA_PERMISSION = 123;
private static final String TAG = "homePage";
private Camera mCamera;
private CameraPreview mCameraPreview;
private boolean cameraPermission() {
int CameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
List<String> cameraPermissionNeeded = new ArrayList<>();
if (CameraPermission != PackageManager.PERMISSION_GRANTED) {
cameraPermissionNeeded.add(Manifest.permission.CAMERA);
}
if (!cameraPermissionNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this,
cameraPermissionNeeded.toArray(new String[cameraPermissionNeeded.size()]),
CAMERA_PERMISSION);
return false;
}
return true;
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String permissions[],
@NonNull int[] grantResults) {
switch(requestCode) {
case CAMERA_PERMISSION:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
return;
}else {
Toast.makeText(this, "Certain permissions needed to continue", Toast.LENGTH_SHORT).show();
}
break;
}
}
private boolean hasCamera() {
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) {
return true;
}else {
AlertDialog camAlert = new AlertDialog.Builder(homePage.this).create();
camAlert.setTitle("Alert");
camAlert.setMessage("there is no usable camera");
camAlert.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
camAlert.show();
return false;
}
}
@SuppressWarnings("deprecation")
public static android.hardware.Camera getCameraInstance() {
android.hardware.Camera c = null;
try {
c = android.hardware.Camera.open();
}
catch (Exception e) {
Log.d(TAG, "camera in use or does not exist");
}
return c;
}
private void releaseCamera(){
if (mCamera != null){
mCamera.release();
mCamera = null;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_page);
cameraPermission();
hasCamera();
mCamera = getCameraInstance();
mCameraPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
}
@Override
protected void onPause() {
super.onPause();
releaseCamera();
}
@Override
protected void onResume() {
super.onResume();
hasCamera();
mCamera.stopPreview();
if (this.mCamera == null) {
mCamera = getCameraInstance();
mCameraPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
}
}
@Override
public void onStart() {
super.onStart();
if (mCamera == null) {
mCamera = getCameraInstance();
mCameraPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
releaseCamera();
}
}
cameraPreview.java
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
import static android.content.ContentValues.TAG;
@SuppressWarnings("deprecation")
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
this.mCamera = camera;
this.mSurfaceHolder = this.getHolder();
this.mSurfaceHolder.addCallback(this);
this.mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
private void releaseCamera() {
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
//==================logcat points out this line===================
mCamera.setPreviewDisplay(surfaceHolder);
//================================================================
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
releaseCamera();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
if (mSurfaceHolder.getSurface() == null) {
return;
}
try {
mCamera.stopPreview();
} catch (Exception e) {
}
try {
mCamera.stopPreview();
} catch (Exception e) {
}
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (Exception e) {
//blank
}
}
}
logcat的
08-09 11:48:17.192 8075-8075/? I/art: Late-enabling -Xcheck:jni
08-09 11:48:17.223 8075-8082/? E/art: Failed sending reply to debugger: Broken pipe
08-09 11:48:17.224 8075-8082/? I/art: Debugger is no longer active
08-09 11:48:17.224 8075-8082/? I/art: Starting a blocking GC Instrumentation
08-09 11:48:17.319 8075-8075/? W/System: ClassLoader referenced unknown path: /data/app/hernanrazo.camera-1/lib/arm64
08-09 11:48:17.331 8075-8075/? I/InstantRun: starting instant run server: is main process
08-09 11:48:17.394 8075-8075/? W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
08-09 11:48:17.544 8075-8128/? I/Adreno: QUALCOMM build : 6818200, Idb2b4cb785
Build Date : 11/17/16
OpenGL ES Shader Compiler Version: XE031.09.00.04
Local Branch : N25
Remote Branch :
Remote Branch :
Reconstruct Branch :
08-09 11:48:17.565 8075-8128/? I/OpenGLRenderer: Initialized EGL, version 1.4
08-09 11:48:17.565 8075-8128/? D/OpenGLRenderer: Swap behavior 1
08-09 11:48:24.832 8075-8075/hernanrazo.camera W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
08-09 11:48:24.832 8075-8075/hernanrazo.camera W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
08-09 11:48:28.527 8075-8075/hernanrazo.camera I/Choreographer: Skipped 32 frames! The application may be doing too much work on its main thread.
08-09 11:48:28.914 8075-8075/hernanrazo.camera W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
08-09 11:48:43.705 8075-8075/hernanrazo.camera D/AndroidRuntime: Shutting down VM
08-09 11:48:43.706 8075-8075/hernanrazo.camera E/AndroidRuntime: FATAL EXCEPTION: main
Process: hernanrazo.camera, PID: 8075
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.Camera.setPreviewDisplay(android.view.SurfaceHolder)' on a null object reference
at hernanrazo.camera.CameraPreview.surfaceCreated(CameraPreview.java:36)
at android.view.SurfaceView.updateWindow(SurfaceView.java:618)
at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:247)
at android.view.View.dispatchWindowVisibilityChanged(View.java:10357)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1544)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6338)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
at android.view.Choreographer.doCallbacks(Choreographer.java:686)
at android.view.Choreographer.doFrame(Choreographer.java:621)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6121)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
我應該只是叫'mCamera.release();'而不是'releaseCamera();' ? –
嘗試在releaseCamera()函數中刪除mCamera = null。 – Chefes
這樣做會消除nullPointerException錯誤,但logcat現在告訴我相機正在使用Camera.release()之後被調用 –