android – 如何在调用Camera时解决ANR错误?

我在主菜单中有两个按钮.我按下第一个按钮时调用相机.在这里,我没有遇到任何问题.相机正常工作.拍完照片后,我回到主菜单,再次按下第一个按钮.我在这里得到了这个问题.相机正确调用.但是当我拍照时,我得到了ANR错误(原因:keyDispatchingTimedOut).如何解决这个问题?

编辑::

我正在使用以下代码,

按钮监听器,

Button imageButton = (Button) findViewById(R.id.button1);
imageButton.setOnClickListener(new  View.OnClickListener() {

    public void onClick(View arg0) {
    Intent intent = new Intent();
    intent.setClass(activity, ImageActivity.class);
    startActivity(intent);
    }
});

ImageActivity.java

public class ImageActivity extends Activity implements SurfaceHolder.Callback {
    private Camera camera = null;
    private SurfaceHolder surfaceHolder = null;
    private boolean previewRunning = false;
    private Button btnDone, btnCapture, btnRetake;
    private Bitmap mBitmap;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.surface_screen);
        SurfaceView surfaceView = (SurfaceView) findViewById(R.id.camerapreview);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        surfaceHolder.setFixedSize(getWindow().getWindowManager()
                .getDefaultDisplay().getWidth(), getWindow().getWindowManager()
                .getDefaultDisplay().getHeight());
        LayoutInflater  controlInflater = LayoutInflater.from(getBaseContext());

        final View viewControl = controlInflater.inflate(R.layout.control, null);
        LayoutParams layoutParamsControl = new LayoutParams(
                LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        activity.addContentView(viewControl, layoutParamsControl);

        btnCapture = (Button) findViewById(R.id.takepicture);

        btnDone = (Button) findViewById(R.id.send);

        btnCapture.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                camera.takePicture(null, picCalBac, picCalBac);
            }
        });


    Camera.PictureCallback picCalBac = new PictureCallback() {

        public void onPictureTaken(byte[] data, Camera camera) {
            if (data != null) {
                mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            }
        }
    };

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        if (previewRunning) {
            camera.stopPreview();
        }
        try {
            camera.setPreviewDisplay(surfaceHolder);
        } catch (IOException e) {
            Log.d("IOException", e.getMessage());
        }
        camera.startPreview();
        previewRunning = true;
    }

    public void surfaceCreated(SurfaceHolder arg0) {
        camera = Camera.open(0);
    }

    public void surfaceDestroyed(SurfaceHolder arg0) {
        camera.stopPreview();
        previewRunning = false;
        camera.release();
    }
}
您可能在搜索错误时经历了this link.

虽然我从未遇到过这样的问题,但在互联网上阅读后,这就是我的理解:

说明:

ANR or Application Not Responding error occurs when a process
on the main thread takes too long (something like > 5 seconds). Android
kills that process and any related by design to spare the device’s
resources.

The solution is to run resource-expensive tasks on another thread, and
then post, or update the main thread accordingly.

见:Android ANR keyDispatchingTimedOut

因此,在您的情况下,您可能会与长时间运行且Android杀死它们的线程冲突两个不同的线程.下一个相关代码也会受到影响.

因此,更好地对代码进行分类,在不同的Thread,Handler中编写每个新任务,如果您正在执行UI任务,请使用runOnUIThread.异步任务也非常方便.

另一件事是尝试删除其他代码的依赖.写一些默认值,如果没有正确完成,你可以将用户送回第一个任务.

我相信错误来自您的编码样式,而不是因为代码中的任何特定错误.

您需要改进您的特定代码才能有效地执行,并且看到这两个链接:

> Design for Responsiveness
> Painless Threading

编辑:

我在某处读到并发现有效的是,

如何调查ANR?

首先,查看代码并查找可用的点和长时间运行的操作.示例可以包括在事件线程内使用套接字,锁,线程休眠和其他阻塞操作.你应该确保这些都发生在不同的线程中.如果没有任何问题,请使用DDMS并启用线程视图.这会显示应用程序中的所有线程与您拥有的跟踪类似.重现ANR,同时刷新主线程.这应该向你展示ANR时正在发生的事情

如果ANR是由于线程引起的?

你可以为此用户服务,
所以你的应用程序可以在service.onStart()中执行耗时的任务,
在用于启动服务的意图中传递数据(例如).

但是,Services在主应用程序线程上执行.如果单独的
需要线程,它可以由onStart()内的服务创建.

已经有一个内置类可以做到这一点:IntentService

还找到了一个有用的库应用程序SalomonBrys/ANR-WatchDog

https://stackoverflow.com/questions/8543486/how-to-resolve-the-anr-error-while-invoking-the-camera

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:android – 如何在调用Camera时解决ANR错误?