Android 当片段包含摄影机预览时,ViewPager滑动滞后

Android 当片段包含摄影机预览时,ViewPager滑动滞后,android,android-fragments,camera,zbar,Android,Android Fragments,Camera,Zbar,我有一个三选项卡的设置,使用一个ViewPager和3个片段。其中一个片段实现了一个二维码扫描仪(ZBarScanner),该扫描仪用摄像机设备的实时视图填充整个片段 我发现这个摄像头视图会导致用户界面严重滞后。在标签之间滑动的动画要慢得多,应用程序的CPU使用率也大幅增加。运行traceview显示扫描仪库的“onPreviewFrame”方法占用了大部分处理器时间 我尝试过使用offscreenPageLimit-我发现需要将其设置为2以保持摄影机视图处于活动状态,否则由于反复启动和关闭摄影

我有一个三选项卡的设置,使用一个ViewPager和3个片段。其中一个片段实现了一个二维码扫描仪(ZBarScanner),该扫描仪用摄像机设备的实时视图填充整个片段

我发现这个摄像头视图会导致用户界面严重滞后。在标签之间滑动的动画要慢得多,应用程序的CPU使用率也大幅增加。运行traceview显示扫描仪库的“onPreviewFrame”方法占用了大部分处理器时间

我尝试过使用offscreenPageLimit-我发现需要将其设置为2以保持摄影机视图处于活动状态,否则由于反复启动和关闭摄影机视图,在刷卡时会出现令人难以置信的严重滞后

如何减少相机预览在我的应用程序中产生的延迟


如果有帮助的话,我可以发布代码,但这太简单了。

我花了很多时间和咖啡,但找到了问题的原因。 使用SurfaceView显示预览时出现的问题

使用TextureView显示预览

这将有助于:

祝你好运

更新:添加了TextureView示例

CameraModule.java

public class CameraModule implements SurfaceTextureListener {
    private Camera mCamera;

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        mCamera = getCamera();

        try {
            mCamera.setPreviewTexture(surface);
            mCamera.startPreview();
        } catch (IOException ioe) {
            // Something bad happened
        }
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        // Ignored, Camera does all the work for us
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        mCamera.stopPreview();
        mCamera.release();
        return true;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        // Invoked every time there's a new Camera preview frame
    }

    private Camera getCamera() {
        Camera cam = null;

        try {
            cam = Camera.open();
        } catch (RuntimeException e) {
            loggerManager.error("Camera not available");
        }

        return cam;
    }
}
public class CameraFragment extends Fragment {

    // You create an instance of the module. I use a singleton.
    CameraModule mCameraModule = new CameraModule();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_camera, container, false);

        TextureView mTextureView = (TextureView) view.findViewById(R.id.camera_preview);
        mTextureView.setSurfaceTextureListener(mCameraModule);

        return view;
    }
}
CameraFragment.java

public class CameraModule implements SurfaceTextureListener {
    private Camera mCamera;

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        mCamera = getCamera();

        try {
            mCamera.setPreviewTexture(surface);
            mCamera.startPreview();
        } catch (IOException ioe) {
            // Something bad happened
        }
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        // Ignored, Camera does all the work for us
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        mCamera.stopPreview();
        mCamera.release();
        return true;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        // Invoked every time there's a new Camera preview frame
    }

    private Camera getCamera() {
        Camera cam = null;

        try {
            cam = Camera.open();
        } catch (RuntimeException e) {
            loggerManager.error("Camera not available");
        }

        return cam;
    }
}
public class CameraFragment extends Fragment {

    // You create an instance of the module. I use a singleton.
    CameraModule mCameraModule = new CameraModule();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_camera, container, false);

        TextureView mTextureView = (TextureView) view.findViewById(R.id.camera_preview);
        mTextureView.setSurfaceTextureListener(mCameraModule);

        return view;
    }
}
fragment\u camera.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000"
    android:orientation="vertical">

    <TextureView
        android:id="@+id/camera_preview"
        android:layout_width="match_parent"
        android:background="#000"
        android:layout_height="match_parent" />


</RelativeLayout>


祝你好运

如何减少相机预览在我的应用程序中产生的延迟?您可以购买更强大的设备。。。这也是一个有点扼杀用户界面。。。刷到二维扫描仪?而不是称之为扫描器意图?@Selvin很好。我正在使用我的Nexus5,它相当强大,在我运行的任何应用程序中都没有给我带来任何问题。因此,它让我相信我可以优化我接近目标的方式app@Selvin关于您的编辑:我更希望QR扫描是独立的,以实现无缝的用户体验。这将是应用程序试图实现的目标的一个组成部分。当片段切换(或视图/片段不可见)时,跳过
onPreviewFrame
中的处理(fx带有一些标记,我不知道,
ViewPager.OnPageChangeListener.onPageScrollStateChanged
看起来很有希望),这解决了您的问题吗?我遇到的另一个问题是,当我离开当前活动(其中包含带有摄像头片段的viewpager)(surfaceview)以开始一个新活动时,我尝试返回。。。它很慢。至少有2-3秒的延迟。离开和返回活动时(可能是因为相机正在重新启动和释放)。我该如何解决这个问题?请帮忙!