如何在调用相机时解决ANR错误?

bha*_*ath 3 android android-camera android-anr-dialog

我在主菜单中有两个按钮.我按下第一个按钮时调用相机.在这里,我没有遇到任何问题.相机正常工作.拍完照片后,我回到主菜单,再次按下第一个按钮.我在这里得到了这个问题.相机正确调用.但是我ANR error (Reason: 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);
    }
});
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

MKJ*_*ekh 9

搜索错误时,您可能已经浏览了此链接.

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

说明:

当主线程上的进程花费太长时间(类似> 5秒)时,会发生ANR或应用程序无响应错误.Android通过设计杀死该进程和任何相关的进程以节省设备的资源.

解决方案是在另一个线程上运行资源昂贵的任务,然后发布或相应地更新主线程.

请参阅:Android ANR keyDispatchingTimedOut

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

因此,最好对代码进行分类,将每个新任务写入不同的内容Thread,Handler,如果您正在执行UI任务,请使用runOnUIThread.Async Task也很方便.

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

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

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

  1. 响应性设计
  2. 无痛的线程

编辑:

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

如何调查ANR?

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

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

您可以为此使用Service,因此您的应用程序可以在service.onStart()中执行耗时的任务,在用于启动服务的intent中传递数据(例如).

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

已经有一个内置类来执行此操作:IntentService

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


Lal*_*ani 6

Android applications normally run entirely on a single (i.e. main) thread.这意味着,任何应用程序在主线程需要做的long time完成可以触发ANR dialog,因为您的应用程序是不是给自己一个机会来处理input event或者我ntent broadcast在这种情况下.所以你可以使用StrictMode,以帮助找到潜在的长时间运行的操作,作为您可能不小心做主线程的网络或数据库操作.如果你发现你的感觉有问题的违规行为,有各种各样的工具来帮助解决这些问题:threads,Handler,AsyncTask,IntentService,etc.Also记住,它是从哪里来的API Level 9

示例代码从在早期使Application,Activity或其它应用程序组件的onCreate()方法:

 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                 .detectDiskReads()
                 .detectDiskWrites()
                 .detectNetwork()   // or .detectAll() for all detectable problems
                 .penaltyLog()
                 .build());
         StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                 .detectLeakedSqlLiteObjects()
                 .detectLeakedClosableObjects()
                 .penaltyLog()
                 .penaltyDeath()
                 .build());
Run Code Online (Sandbox Code Playgroud)


use*_*305 5

我想你已经知道了,

单线程模型可以产生在不考虑影响Android应用程序的性能较差.由于所有操作都发生在执行长操作的单个线程上,例如网络访问或数据库查询,因此该线程将阻止整个用户界面.长时间操作正在进行中,不会发送任何事件,包括绘图事件.*从用户的角度来看,应用程序显示为挂起*.更糟糕的是,如果UI线程被阻止超过几秒钟(当前约5秒),则向用户呈现臭名昭着的"应用程序无响应"(ANR)对话框.

当在"主"线程中发生一些长操作时,会发生ANR.这是事件循环线程,如果它很忙,Android无法处理应用程序中的任何其他GUI事件,从而抛出ANR对话框.

什么触发ANR?

在Android中,应用程序响应性由活动管理器和Window Manager系统服务监视.当Android检测到以下某种情况时,它将显示特定应用程序的ANR对话框:

* No response to an input event (e.g. key press, screen touch) within 5 seconds
* A BroadcastReceiver hasn't finished executing within 10 seconds
Run Code Online (Sandbox Code Playgroud)

如何解决它请看设计响应

编辑:

因此,尝试使用其他单独的工作线程,处理程序,AsyncTask或UIThread为您的相机(媒体记录器)而不是活动的主线程.

1).不要"adb shell cat /data/anr/traces.txt"看到你的应用程序正忙于在这一点上做的事情.这是您需要采取的第一步:了解您的应用正在做什么导致ANR.

当ANR发生时,所有进程的堆栈都被写入该文件,并且该进程首先被控制为ANR.所有这一切都是转储文件,以便您可以查看它.因此,您只想在ANR之后的某个时间查看它,然后再发生另一个ANR.

2).如果没有任何问题,请使用DDMS并启用线程视图.这会显示应用程序中的所有线程与您拥有的跟踪类似.重现ANR,同时刷新主线程.这应该向你展示ANR时正在发生的事情.

更多信息请访问http://android-developers.blogspot.com/2009/05/painless-threading.html