Android:实现片段问题(膨胀异常)

时间:2016-02-18 10:33:03

标签: android android-fragments inflate-exception

错误:02-18 10:10:24.260: E/AndroidRuntime(5769): java.lang.RuntimeException: Unable to start activity ComponentInfo{org.opencv.samples.facedetect/activity.CameraTest}: android.view.InflateException: Binary XML file line #33: Error inflating class fragment

使用人脸检测相机。

  • 让用户个人资料页面上有一个按钮来测试人脸检测相机是否正常工作
  • 点击按钮时会打开 FaceDetectTest.class ,其中 test_activity.xml 包含 fdActivity.class 片段。
  • 这已经完成,所以我可以在页面顶部有一个工具栏返回上一个屏幕,所以我不必加载FdActivity类

我有一个使用面部检测的应用程序。使用开放式CV我有一个运行面部检测代码的fdActivity类。我已将其从活动更改为片段,以便我可以在整个代码中使用它。

例如,我有一个用户个人资料页面,他们可以点击按钮查看人脸检测是否有效。这将打开一个名为TestActivity的活动,该活动实现fdActivity片段以查看人脸检测相机&顶部还有一个工具栏,用于返回上一页。

TestActivity.class 使用的test_detec_activity.xml test_detection_activity.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >

<RelativeLayout
    android:id="@+id/linearLayout1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/bg_login"
    android:orientation="vertical" >       

    <Button
        android:id="@+id/btnReturnProfile"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/Profile" />

    <TextView
        android:id="@+id/headingText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginLeft="35dp"
        android:layout_marginStart="35dp"
        android:layout_toRightOf="@+id/btnReturnProfile"
        android:layout_toEndOf="@+id/btnReturnProfile"
        android:text="@string/faceDetetRequir" />

</RelativeLayout>

<fragment
    android:id="@+id/fragment1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_below="@+id/linearLayout1"        
    class="openCV.facedetect.FdActivity" />

TestActivity.class

    package activity;

import org.opencv.samples.facedetect.R;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.Button;
import helper.SessionManager;

public class CameraTest extends FragmentActivity implements View.OnClickListener{

    private Button btnReturnProfile;
    private SessionManager session;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.test_detection_activity);

        super.onCreate(savedInstanceState);

        session = new SessionManager(getApplicationContext());
        setViewsFromLayout();
        setListenersFromLayout();

    }


    @Override
    public void onClick(View v) {
        if (v == btnReturnProfile){
            launchIntentToProfilePage();
            addCheckedCameraToSession();
            finish();
        }

    }
    private void addCheckedCameraToSession(){
        session.setCheckedCameraBeforeTest(true);
    }

    private void launchIntentToProfilePage(){
        Intent intent = new Intent(getApplicationContext(), UserProfile.class);
        startActivity(intent);
    }

    private void setViewsFromLayout(){
        btnReturnProfile = (Button) findViewById(R.id.btnRegister);
    }

    private void setListenersFromLayout(){
        btnReturnProfile = (Button) findViewById(R.id.btnReturnProfile);
    }

}

片段代码:(改变了openCV的fdActivity)

    package openCV.facedetect;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.samples.facedetect.R;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;

public class FdActivity extends Fragment implements CvCameraViewListener2 {

    private static final String    TAG                 = "OCVSample::Activity";
    private static final Scalar    FACE_RECT_COLOR     = new Scalar(0, 255, 0, 255);
    public static final int        JAVA_DETECTOR       = 0;
    public static final int        NATIVE_DETECTOR     = 1;

    private MenuItem               mItemFace50;
    private MenuItem               mItemFace40;
    private MenuItem               mItemFace30;
    private MenuItem               mItemFace20;
    private MenuItem               mItemType;

    private Mat                    mRgba;
    private Mat                    mGray;
    private File                   mCascadeFile;
    private CascadeClassifier      mJavaDetector;
    private DetectionBasedTracker  mNativeDetector;

    private int                    mDetectorType       = JAVA_DETECTOR;
    private String[]               mDetectorName;

    private float                  mRelativeFaceSize   = 0.2f;
    private int                    mAbsoluteFaceSize   = 0;

    private CameraBridgeViewBase   mOpenCvCameraView;

    private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(getActivity()) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
            case LoaderCallbackInterface.SUCCESS:
            {
                Log.i(TAG, "OpenCV loaded successfully");

                // Load native library after(!) OpenCV initialization
                System.loadLibrary("detection_based_tracker");

                try {
                    // load cascade file from application resources
                    InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface);
                    File cascadeDir = getActivity().getDir("cascade", Context.MODE_PRIVATE);
                    mCascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml");
                    FileOutputStream os = new FileOutputStream(mCascadeFile);

                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = is.read(buffer)) != -1) {
                        os.write(buffer, 0, bytesRead);
                    }
                    is.close();
                    os.close();

                    mJavaDetector = new CascadeClassifier(mCascadeFile.getAbsolutePath());
                    if (mJavaDetector.empty()) {
                        Log.e(TAG, "Failed to load cascade classifier");
                        mJavaDetector = null;
                    } else
                        Log.i(TAG, "Loaded cascade classifier from " + mCascadeFile.getAbsolutePath());

                    mNativeDetector = new DetectionBasedTracker(mCascadeFile.getAbsolutePath(), 0);

                    cascadeDir.delete();

                } catch (IOException e) {
                    e.printStackTrace();
                    Log.e(TAG, "Failed to load cascade. Exception thrown: " + e);
                }

                mOpenCvCameraView.enableView();
            } break;
            default:
            {
                super.onManagerConnected(status);
            } break;
        }
        }
    };

    public FdActivity() {
        mDetectorName = new String[2];
        mDetectorName[JAVA_DETECTOR] = "Java";
        mDetectorName[NATIVE_DETECTOR] = "Native (tracking)";

        Log.i(TAG, "Instantiated new " + this.getClass());
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return inflater.inflate(R.layout.face_detect_surface_view, container, false);
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.i(TAG, "called onCreate");
        super.onCreate(savedInstanceState);
        getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);


        mOpenCvCameraView = (CameraBridgeViewBase) getView().findViewById(R.id.fd_activity_surface_view);
        mOpenCvCameraView.setCameraIndex(1);
        mOpenCvCameraView.setCvCameraViewListener(this);
    }

    @Override
    public void onPause()
    {
        super.onPause();
        if (mOpenCvCameraView != null)
            mOpenCvCameraView.disableView();
    }

    @Override
    public void onResume()
    {
        super.onResume();
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, getActivity(), mLoaderCallback);
    }

    public void onDestroy() {
        super.onDestroy();
        mOpenCvCameraView.disableView();
    }

    public void onCameraViewStarted(int width, int height) {
        mGray = new Mat();
        mRgba = new Mat();
    }

    public void onCameraViewStopped() {
        mGray.release();
        mRgba.release();
    }

    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {

        mRgba = inputFrame.rgba();
        mGray = inputFrame.gray();

        if (mAbsoluteFaceSize == 0) {
            int height = mGray.rows();
            if (Math.round(height * mRelativeFaceSize) > 0) {
                mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);
            }
            mNativeDetector.setMinFaceSize(mAbsoluteFaceSize);
        }

        MatOfRect faces = new MatOfRect();

        if (mDetectorType == JAVA_DETECTOR) {
            if (mJavaDetector != null)
                mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2, // TODO: objdetect.CV_HAAR_SCALE_IMAGE
                        new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());
        }
        else if (mDetectorType == NATIVE_DETECTOR) {
            if (mNativeDetector != null)
                mNativeDetector.detect(mGray, faces);
        }
        else {
            Log.e(TAG, "Detection method is not selected!");
        }

        Rect[] facesArray = faces.toArray();
        for (int i = 0; i < facesArray.length; i++)
            Core.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), FACE_RECT_COLOR, 3);

        return mRgba;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        Log.i(TAG, "called onOptionsItemSelected; selected item: " + item);
        if (item == mItemFace50)
            setMinFaceSize(0.5f);
        else if (item == mItemFace40)
            setMinFaceSize(0.4f);
        else if (item == mItemFace30)
            setMinFaceSize(0.3f);
        else if (item == mItemFace20)
            setMinFaceSize(0.2f);
        else if (item == mItemType) {
            int tmpDetectorType = (mDetectorType + 1) % mDetectorName.length;
            item.setTitle(mDetectorName[tmpDetectorType]);
            setDetectorType(tmpDetectorType);
        }
        return true;
    }

    private void setMinFaceSize(float faceSize) {
        mRelativeFaceSize = faceSize;
        mAbsoluteFaceSize = 0;
    }

    private void setDetectorType(int type) {
        if (mDetectorType != type) {
            mDetectorType = type;

            if (type == NATIVE_DETECTOR) {
                Log.i(TAG, "Detection Based Tracker enabled");
                mNativeDetector.start();
            } else {
                Log.i(TAG, "Cascade detector enabled");
                mNativeDetector.stop();
            }
        }
    }
}

face_detect_surface.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >

<org.opencv.android.JavaCameraView
    android:id="@+id/fd_activity_surface_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true" />

我是使用片段的新手,我只是在寻找一种方法来重用fdActivity而不是为不同的屏幕制作不同版本的负载。

由于

编辑堆栈跟踪

    02-18 11:20:02.315: E/AndroidRuntime(7273): java.lang.RuntimeException: Unable to start activity ComponentInfo{org.opencv.samples.facedetect/activity.CameraActivity}: android.view.InflateException: Binary XML file line #33: Error inflating class fragment
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2049)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2083)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.app.ActivityThread.access$600(ActivityThread.java:134)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1233)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.os.Looper.loop(Looper.java:137)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.app.ActivityThread.main(ActivityThread.java:4697)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at java.lang.reflect.Method.invokeNative(Native Method)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at java.lang.reflect.Method.invoke(Method.java:511)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at dalvik.system.NativeStart.main(Native Method)
02-18 11:20:02.315: E/AndroidRuntime(7273): Caused by: android.view.InflateException: Binary XML file line #33: Error inflating class fragment
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:255)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.app.Activity.setContentView(Activity.java:1879)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at activity.CameraActivity.onCreate(CameraActivity.java:25)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.app.Activity.performCreate(Activity.java:4539)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2013)
02-18 11:20:02.315: E/AndroidRuntime(7273):     ... 11 more
02-18 11:20:02.315: E/AndroidRuntime(7273): Caused by: java.lang.NullPointerException
02-18 11:20:02.315: E/AndroidRuntime(7273):     at openCV.facedetect.FaceDetectionFragment.onCreateView(FaceDetectionFragment.java:66)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:806)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1010)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1108)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.app.Activity.onCreateView(Activity.java:4317)
02-18 11:20:02.315: E/AndroidRuntime(7273):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:673)
02-18 11:20:02.315: E/AndroidRuntime(7273):     ... 21 more

2 个答案:

答案 0 :(得分:0)

我想问题出在onCreate()活动的CameraTest

尝试在super.onCreate()之前致电setContentView()

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.test_detection_activity);

    session = new SessionManager(getApplicationContext());
    setViewsFromLayout();
    setListenersFromLayout();

}

答案 1 :(得分:0)

问题出在你的setContentView()方法中,用于给类充气。

@Override
protected void onCreate(Bundle savedInstanceState) {       
    super.onCreate(savedInstanceState);
    setContentView(R.layout.test_detection_activity);
    session = new SessionManager(getApplicationContext());
    setViewsFromLayout();
    setListenersFromLayout();

另外,对于使用片段,您应该在MainActivity中使用FrameLayout。之后,您可以将片段调用到该帧。像:

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/content_frame"
>

之后点击任何小部件调用:

 android.support.v4.app.FragmentManager fragmentManager=getSupportFragmentManager();
        android.support.v4.app.FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.content_frame, new SampleFragment());
        fragmentTransaction.addToBackStack(null);
        fragmentTransaction.commit();