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)
搜索错误时,您可能已经浏览了此链接.
虽然我从未遇到过这样的问题,但在互联网上阅读后,这就是我的理解:
说明:
当主线程上的进程花费太长时间(类似> 5秒)时,会发生ANR或应用程序无响应错误.Android通过设计杀死该进程和任何相关的进程以节省设备的资源.
解决方案是在另一个线程上运行资源昂贵的任务,然后发布或相应地更新主线程.
请参阅:Android ANR keyDispatchingTimedOut
因此,在您的情况下,您可能会与长时间运行且Android杀死它们的线程冲突两个不同的线程.下一个相关代码也会受到影响.
因此,最好对代码进行分类,将每个新任务写入不同的内容Thread,Handler
,如果您正在执行UI任务,请使用runOnUIThread
.Async Task
也很方便.
另一件事是尝试删除其他代码的依赖.写一些默认值,如果没有正确完成,你可以将用户送回第一个任务.
我相信错误来自您的编码样式,而不是因为代码中的任何特定错误.
您需要改进您的特定代码才能有效地执行,并且看到这两个链接:
编辑:
这是我在某处读到的,发现有效的是,
如何调查ANR?
首先,查看代码并查找可用的点和长时间运行的操作.示例可以包括在事件线程内使用套接字,锁,线程休眠和其他阻塞操作.你应该确保这些都发生在不同的线程中.如果没有任何问题,请使用DDMS并启用线程视图.这会显示应用程序中的所有线程与您拥有的跟踪类似.重现ANR,同时刷新主线程.这应该向你展示ANR时正在发生的事情
如果ANR是由于线程引起的?
您可以为此使用Service,因此您的应用程序可以在service.onStart()中执行耗时的任务,在用于启动服务的intent中传递数据(例如).
但是,Services在主应用程序线程上执行.如果需要单独的线程,则可以由onStart()内的服务创建.
已经有一个内置类来执行此操作:IntentService
还找到了一个有用的图书馆应用程序 SalomonBrys/ANR-WatchDog
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)
我想你已经知道了,
在单线程模型可以产生在不考虑影响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
归档时间: |
|
查看次数: |
4373 次 |
最近记录: |