2017-06-19 72 views
0

我试图在对话框中显示相机预览。每次我尝试运行应用程序,我有以下错误:'Surface.View.SurfaceHolder android.view.SurfaceView.getHolder()'SurfaceView中的空对象引用

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.triple.m.crabzilla.pepers/com.triple.m.crabzilla.pepers.PersonalizedPermissionDialog}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.SurfaceHolder android.view.SurfaceView.getHolder()' on a null object reference 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2981) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3042) 
    at android.app.ActivityThread.-wrap14(ActivityThread.java) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1639) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:154) 
    at android.app.ActivityThread.main(ActivityThread.java:6776) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410) 
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.SurfaceHolder android.view.SurfaceView.getHolder()' on a null object reference 
    at com.triple.m.crabzilla.pepers.PersonalExamples.CameraPreview.<init>(CameraPreview.java:36) 
    at com.triple.m.crabzilla.pepers.PersonalExamples.CameraExample.<init>(CameraExample.java:28) 
    at com.triple.m.crabzilla.pepers.PersonalizedPermissionDialog.setView(PersonalizedPermissionDialog.java:156) 
    at com.triple.m.crabzilla.pepers.PersonalizedPermissionDialog.onStart(PersonalizedPermissionDialog.java:71) 
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1256) 
    at android.app.Activity.performStart(Activity.java:6965) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2934) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3042)  
    at android.app.ActivityThread.-wrap14(ActivityThread.java)  
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1639)  
    at android.os.Handler.dispatchMessage(Handler.java:102)  
    at android.os.Looper.loop(Looper.java:154)  
    at android.app.ActivityThread.main(ActivityThread.java:6776)  
    at java.lang.reflect.Method.invoke(Native Method)  
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)  
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)  

这是怎么了,我叫它:

public class CameraExample extends AnimatedViewContainer { 

    private final static String TAG = "CameraExample"; 

    private Context mContext; 
    private SurfaceView mPreview; 
    public CameraExample(Context context, int i) { 
     super(context, i); 

     mContext = context; 
     mPreview = (SurfaceView) findViewById(R.id.surfaceView); 
     CameraPreview mgr = new CameraPreview(mContext, mPreview); 
     mgr.init(); 


    } 

    @Override 
    public void onCreateViewContent(LayoutInflater layoutInflater, ViewGroup parentGroup, View[] containerViews, int index) { 
     containerViews[index] = layoutInflater.inflate(R.layout.example_camera, parentGroup, false); 
     FrameLayout previewFrame = (FrameLayout) containerViews[index].findViewById(R.id.preview); 

     // Add preview for inflation 
     previewFrame.addView(mPreview); 

    } 
} 

这是XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
...  
    <FrameLayout 
     android:id="@+id/preview" 
     android:layout_width="match_parent" 
     android:layout_height="@dimen/photo_example_height"> 
     <SurfaceView 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:id="@+id/surfaceView" /> 
    </FrameLayout> 
</LinearLayout> 

CameraPreview我使用的是一个非常基本的通用相机管理器,如下所示:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 

    private static String TAG = "CameraManager"; 

    private Context mContext = null; 
    private SurfaceView mPreview = null; 
    private SurfaceHolder mHolder = null; 
    private Camera mCamera = null; 
    private int mFrontFaceID = -1; 
    private int mBackFaceID = -1; 
    private int mActualFacingID = -1; 

    public CameraPreview(Context context, SurfaceView preview) { 
     super(context); 
     mContext = context; 
     mPreview = preview; 
     mHolder = mPreview.getHolder(); 
     mHolder.addCallback(this); 
    } 

    //called in onCreate 
    public void init() { 
     Camera.CameraInfo info = new Camera.CameraInfo(); 
     for (int i = 0; i < Camera.getNumberOfCameras(); i++) { 
      Camera.getCameraInfo(i, info); 
      if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
       mFrontFaceID = i; 
      } 
      if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) { 
       mBackFaceID = i; 
      } 
     } 
     if (mActualFacingID == -1) { 
      if (mFrontFaceID != -1) { 
       mActualFacingID = mFrontFaceID; 
      } else { 
       mActualFacingID = mBackFaceID; 
      } 
     } 
     //At least one one camera will be available because of manifest declaration 
    } 

    //called first on surface created 
    public void start() { 
     Log.i(TAG, "startCamera()"); 
     if (mCamera == null) { 
      mCamera = getCameraInstance(mActualFacingID); 
     } 
     if (mCamera == null) { 
      Log.i(TAG, "can't get camera instance"); 
      return; 
     } 
     try { 
      mCamera.setPreviewDisplay(mHolder); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     setCameraDisplayOrientation(); 
     setBestSupportedSizes(); 
     mCamera.startPreview(); 
    } 

    public void stop() { 
     Log.i(TAG, "stopCamera()"); 
     if (mCamera != null) { 
      mCamera.stopPreview(); 
      mCamera.release(); 
      mCamera = null; 
     } 
    } 

    public void switchFacing() { 
     if (mFrontFaceID == -1 || mBackFaceID == -1) { 
      return; 
     } 
     stop(); 
     if (mActualFacingID == mFrontFaceID) { 
      mActualFacingID = mBackFaceID; 
     } else { 
      mActualFacingID = mFrontFaceID; 
     } 
     start(); 
    } 

    public Camera getCameraInstance(int cameraID) { 
     Camera c = null; 
     if (cameraID != -1) { 
      try { 
       c = Camera.open(cameraID); 
      } catch (Exception e) { 
       e.printStackTrace(); 
       Log.i(TAG, "error opening camera: " + cameraID); 
      } 
     } 
     return c; 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     Log.i(TAG, "surfaceCreated()"); 
     start(); 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
     Log.i(TAG, "surfaceChanged()"); 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     Log.i(TAG, "surfaceDestroyed()"); 
     stop(); 
    } 

    private void setBestSupportedSizes() { 
     if (mCamera == null) { 
      return; 
     } 
     Camera.Parameters parameters = mCamera.getParameters(); 
     List<Point> pictureSizes=getSortedSizes(parameters.getSupportedPictureSizes()); 

     List<Point> previewSizes=getSortedSizes(parameters.getSupportedPreviewSizes()); 

     Point previewResult=null; 
     for (Point size:previewSizes){ 
      float ratio = (float) size.y/size.x; 
      if(Math.abs(ratio-4/(float)3)<0.05){ //Aspect ratio of 4/3 because otherwise the image scales to much. 
       previewResult=size; 
       break; 
      } 
     } 
     Log.i(TAG,"preview: "+previewResult.x+"x"+previewResult.y); 
     Point pictureResult=null; 
     if(previewResult!=null){ 
      float previewRatio=(float)previewResult.y/previewResult.x; 
      for (Point size:pictureSizes){ 
       float ratio = (float) size.y/size.x; 
       if(Math.abs(previewRatio-ratio)<0.05){ 
        pictureResult=size; 
        break; 
       } 
      } 
     } 
     Log.i(TAG,"preview: "+pictureResult.x+"x"+pictureResult.y); 

     if(previewResult!=null && pictureResult!=null){ 
      Log.i(TAG,"best preview: "+previewResult.x+"x"+previewResult.y); 
      Log.i(TAG, "best picture: " + pictureResult.x + "x" + pictureResult.y); 
      parameters.setPreviewSize(previewResult.y, previewResult.x); 
      parameters.setPictureSize(pictureResult.y, pictureResult.x); 
      mCamera.setParameters(parameters); 
      mPreview.setBackgroundColor(Color.TRANSPARENT); //in the case of errors needed 
     }else{ 
      mCamera.stopPreview(); 
      mPreview.setBackgroundColor(Color.BLACK); 
     } 
    } 

    private List<Point> getSortedSizes(List<Camera.Size> sizes) { 
     ArrayList<Point> list = new ArrayList<>(); 

     for (Camera.Size size : sizes) { 
      int height; 
      int width; 
      if (size.width > size.height) { 
       height = size.width; 
       width = size.height; 
      } else { 
       height = size.height; 
       width = size.width; 
      } 
      list.add(new Point(width, height)); 

     } 

     Collections.sort(list, new Comparator<Point>() { 
      @Override 
      public int compare(Point lhs, Point rhs) { 
       long lhsCount = lhs.x * (long) lhs.y; 
       long rhsCount = rhs.x * (long) rhs.y; 
       if (lhsCount < rhsCount) { 
        return 1; 
       } 
       if (lhsCount > rhsCount) { 
        return -1; 
       } 
       return 0; 
      } 
     }); 
     return list; 
    } 

    public void onPictureTaken(byte[] data, Camera camera) { 
     //do something with your picture 
    } 

    //ROTATION 
    private void setCameraDisplayOrientation() { 
     if (mCamera != null) { 
      mCamera.setDisplayOrientation((int) getRotation()); 
     } 
    } 

    @Override 
    public float getRotation() { 
     Camera.CameraInfo info = new Camera.CameraInfo(); 
     Camera.getCameraInfo(mActualFacingID, info); 
     int rotation = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay() 
       .getRotation(); 
     int degrees = 0; 
     switch (rotation) { 
      case Surface.ROTATION_0: 
       degrees = 0; 
       break; 
      case Surface.ROTATION_90: 
       degrees = 90; 
       break; 
      case Surface.ROTATION_180: 
       degrees = 180; 
       break; 
      case Surface.ROTATION_270: 
       degrees = 270; 
       break; 
     } 

     int result; 
     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
      result = (info.orientation + degrees) % 360; 
      result = (360 - result) % 360; // compensate the mirror 
     } else { // back-facing 
      result = (info.orientation - degrees + 360) % 360; 
     } 
     return result; 
    } 

} 

为什么我得到这个错误? 谢谢!

回答

1

变化相机类这样的:

公共类CameraExample扩展AnimatedViewContainer {

private final static String TAG = "CameraExample"; 

private Context mContext; 
private SurfaceView mPreview; 
public CameraExample(Context context, int i) { 
    super(context, i); 
    mContext = context; 

} 

@Override 
public void onCreateViewContent(LayoutInflater layoutInflater, ViewGroup parentGroup, View[] containerViews, int index) { 
    containerViews[index] = layoutInflater.inflate(R.layout.example_camera, parentGroup, false); 
    FrameLayout previewFrame = (FrameLayout) containerViews[index].findViewById(R.id.preview); 

    //this have been line moved here from constructor 
    mPreview = (SurfaceView) findViewById(R.id.surfaceView); 
    CameraPreview mgr = new CameraPreview(mContext, mPreview); 
    mgr.init(); 

    // Add preview for inflation 
    previewFrame.addView(mPreview); 

} 

}

+0

崩溃消失了,但我无法看到预览:( –

+1

我只是解决了你说的例外 –

相关问题