NOTE: attach of thread 'Binder_3' failed 的调试和解决
2014-11-25 11:56
239 查看
近来一直还是在做Camera的应用调试,在调试过程中出现了这样一个问题:
因为目前在做的Camera应用需要做到后台开启并保持录像的功能,因此所有的Camera操作都选择了在另外一个独立的Service中完成,包括Camera对象的初始化,拍照参数的设置,预览参数的设置,录像的参数设置等等都在Service中完成。之所以选择Service显而易见也是为了能保持后台录像的功能。那么说到Service的话就必须说到Service的开启和关闭了,一般的用法都会推荐
context.startService(Intent)和stopService; 或者
context.bindService()和context.unbindService()
但是这两种方式分别会有各自的优点,恰好我所需要达到的目的是两者结合才能实现的,于是我的选择是两者结合来用。
我的调用顺序为先StartService,然后bindService。然后在退出Activity的同时去判断是否正在录像,如果正在录像则转为后台录像模式。否则直接finish Activity释放Service,按这个思路做完功能还算正常,但是出现一个问题。
首先讲下程序框架,首先是主Activity会有预览界面以及三个button分别为拍照,录像和文件预览。其中文件预览为单独的一个Activity来查看录像文件和拍照的图片文件。问题就出在录像过程中跳转到文化间预览的Activity然后再回退到主Activity,此时录像正常。接着我停止录像试图退出应用,然后问题出现了,我是直接操作的BACK键去退出应用,并且Back键的处理为释放服务finish程序。代码如下
开始看似没有什么问题,但是Activity在响应的时候却出现了回退到了停止录像前也就是刚从文件预览界面回来时的画面,并且画面不再刷新。紧接着我试图继续back来退出应用,同样失败了。最终看了很多遍log后,感觉从文件预览界面回退时的操作应该有问题,于是看代码,回退到主Activity的代码如下
简单的说明下两者的区别,
FLAG_ACTIVITY_NEW_TASK
设置此状态,记住以下原则,首先会查找是否存在和被启动的Activity具有相同的亲和性的任务栈(即taskAffinity,注意同一个应用程序中的activity的亲和性一样,所 以下面的a情况会在同一个栈中,前面这句话有点拗口,请多读几遍),如果有,刚直接把这个栈整体移动到前台,并保持栈中的状态不变,即栈中的activity顺序不变,如果没有,则新建一个栈来存放被启动的activity。
FLAG_ACTIVITY_CLEAR_TOP
我们知道Android的窗口类提供了历史栈,我们可以通过stack的原理来巧妙的实现,这里我们在D窗口打开A窗口时在Intent中直接加入标志Intent.FLAG_ACTIVITY_CLEAR_TOP,再次开启A时将会清除该进程空间的所有Activity。
这样解释可能就可以说明问题了,我们开始的back是执行了回退到历史栈中的一个Activity状态了,所以界面不会再刷新,只有继续back才可能找到栈底的Activity并退出,但是问题又出现了。就是程序无法退出,找了好久log终于发现了这个地方
I/AndroidRuntime( 3808): NOTE: attach of thread 'Binder_3' failed
可以看到是以为内Service的bind操作出现了问题,导致Service无法正常释放,Acitivity无法finish。于是继续研究Service的启动和关闭相关的东西,期间查了不少资料也看过不少达人的blog最终找到了办法解决。
上述两种启动Servidce的方法如果混合用的话最好是保证两种方法操作的service对象统一,且均要进行停止service的操作才可以完整的释放service。同时bind的方法在所bind的Activity在finish的时候会自动的unbind释放service。
此处在代码中有个差别是在启动的时候
getApplicationContext().startService(service);
bindPlayerService();
是首先startserice然后bind的,但是后面的finish操作却是如此
stopService(exitIntent);
unBindPlayerService();
可以看到此处的调用直接是stopservice了,并未获取context对象,经过验证恰好是这个地方造成了后面service释放的异常。可能此处不会导致前面说的finish后回到之前正在录像的界面不刷新,但是造成了后面back键无响应程序无法退出的问题。 因此改为
getApplicationContext().stopService(exitIntent);
unBindPlayerService();
跟开启服务的操作保持一致,此时服务释放异常解决。重点却是一个操作对象的不统一造成的,至于更深层次的原因现在暂时无法得知,只能等以后有能力再来做研究了。到此问题解决。耗了3天的问题终于搞定,着实不易。
因为目前在做的Camera应用需要做到后台开启并保持录像的功能,因此所有的Camera操作都选择了在另外一个独立的Service中完成,包括Camera对象的初始化,拍照参数的设置,预览参数的设置,录像的参数设置等等都在Service中完成。之所以选择Service显而易见也是为了能保持后台录像的功能。那么说到Service的话就必须说到Service的开启和关闭了,一般的用法都会推荐
context.startService(Intent)和stopService; 或者
context.bindService()和context.unbindService()
但是这两种方式分别会有各自的优点,恰好我所需要达到的目的是两者结合才能实现的,于是我的选择是两者结合来用。
我的调用顺序为先StartService,然后bindService。然后在退出Activity的同时去判断是否正在录像,如果正在录像则转为后台录像模式。否则直接finish Activity释放Service,按这个思路做完功能还算正常,但是出现一个问题。
首先讲下程序框架,首先是主Activity会有预览界面以及三个button分别为拍照,录像和文件预览。其中文件预览为单独的一个Activity来查看录像文件和拍照的图片文件。问题就出在录像过程中跳转到文化间预览的Activity然后再回退到主Activity,此时录像正常。接着我停止录像试图退出应用,然后问题出现了,我是直接操作的BACK键去退出应用,并且Back键的处理为释放服务finish程序。代码如下
Intent exitIntent = new Intent(getApplicationContext(),CameraService.class); stopService(exitIntent); unBindPlayerService();CameraActivity.this.finish();
开始看似没有什么问题,但是Activity在响应的时候却出现了回退到了停止录像前也就是刚从文件预览界面回来时的画面,并且画面不再刷新。紧接着我试图继续back来退出应用,同样失败了。最终看了很多遍log后,感觉从文件预览界面回退时的操作应该有问题,于是看代码,回退到主Activity的代码如下
public void toPreviewUI(){ Intent intent = new Intent(this, CameraActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); this.finish(); }最后问题锁定在回退时的Flags设置,不应该采用FLAG_ACTIVITY_NEW_TASK,而是采用FLAG_ACTIVITY_CLEAR_TOP
简单的说明下两者的区别,
FLAG_ACTIVITY_NEW_TASK
设置此状态,记住以下原则,首先会查找是否存在和被启动的Activity具有相同的亲和性的任务栈(即taskAffinity,注意同一个应用程序中的activity的亲和性一样,所 以下面的a情况会在同一个栈中,前面这句话有点拗口,请多读几遍),如果有,刚直接把这个栈整体移动到前台,并保持栈中的状态不变,即栈中的activity顺序不变,如果没有,则新建一个栈来存放被启动的activity。
FLAG_ACTIVITY_CLEAR_TOP
我们知道Android的窗口类提供了历史栈,我们可以通过stack的原理来巧妙的实现,这里我们在D窗口打开A窗口时在Intent中直接加入标志Intent.FLAG_ACTIVITY_CLEAR_TOP,再次开启A时将会清除该进程空间的所有Activity。
这样解释可能就可以说明问题了,我们开始的back是执行了回退到历史栈中的一个Activity状态了,所以界面不会再刷新,只有继续back才可能找到栈底的Activity并退出,但是问题又出现了。就是程序无法退出,找了好久log终于发现了这个地方
I/AndroidRuntime( 3808): NOTE: attach of thread 'Binder_3' failed
可以看到是以为内Service的bind操作出现了问题,导致Service无法正常释放,Acitivity无法finish。于是继续研究Service的启动和关闭相关的东西,期间查了不少资料也看过不少达人的blog最终找到了办法解决。
上述两种启动Servidce的方法如果混合用的话最好是保证两种方法操作的service对象统一,且均要进行停止service的操作才可以完整的释放service。同时bind的方法在所bind的Activity在finish的时候会自动的unbind释放service。
此处在代码中有个差别是在启动的时候
getApplicationContext().startService(service);
bindPlayerService();
是首先startserice然后bind的,但是后面的finish操作却是如此
stopService(exitIntent);
unBindPlayerService();
可以看到此处的调用直接是stopservice了,并未获取context对象,经过验证恰好是这个地方造成了后面service释放的异常。可能此处不会导致前面说的finish后回到之前正在录像的界面不刷新,但是造成了后面back键无响应程序无法退出的问题。 因此改为
getApplicationContext().stopService(exitIntent);
unBindPlayerService();
跟开启服务的操作保持一致,此时服务释放异常解决。重点却是一个操作对象的不统一造成的,至于更深层次的原因现在暂时无法得知,只能等以后有能力再来做研究了。到此问题解决。耗了3天的问题终于搞定,着实不易。
相关文章推荐
- arm环境下编译出现下面警告的解决办法 note: the mangling of 'va_list' has changed in GCC 4.4
- 导入项目提示Compilation of JSP File '/xx/xx/xxx.jsp' failed解决办法
- Git pull 出现Unlink of file '.git/objects/pack/.tmp-xxx' failed. Should I try again? (y/n) 解决办法
- Android 解决adb server is out of date. killing... ADB server didn't ACK * failed to star
- ModelSim 添加库问题 Instantiation of 'dffeas' failed 解决办法
- MYSQL提示Can't create a new thread (errno 12)错误的解决办法
- 关于mysql错误:Illegal mix of collations for operation '='的解决
- 【解决问题】'failed to open stream:Permission denied in......'在php出现情况总结
- php当中出现的错误:Use of undefined constant title - assumed 'title'的解决方法
- tomcat 5.5 Cannot create JDBC driver of class '' for connect URL 'null' 配置数据源错误解决办法
- SQL SERVER 2005恢复数据错误解决:The backup set holds a backup of a database other than the existing 'XXX' database
- (菜鸟级别)解决用VC创建新线程易出的问题error C2664: 'CreateThread' : cannot convert parameter 3 from 'unsigned long (void *)' to 'unsigned long (_
- 解决 'Could not convert variant of type (NULL) into type (String)'
- Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (gbk_chinese_ci,COERCIBLE) for operation '=' 一个解决办法(转载)
- TZipMaster出现错误:failed to load 'unzdll.dll'的解决方法
- [Visual Studio 2010]如何解决错误CoClass 'xx' can be used only as one of its applicable interfaces
- Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (gbk_chinese_ci,COERCIBLE) for operation '=' 一个解决办法
- Cannot create JDBC driver of class '' for connect URL 'null'解决方法2——对我有效
- 使用TOMCAT5.5连接池连接mysql(解决Cannot create JDBC driver of class '' for connect URL 'null' 及can not load org.gjt.mm.mysql.Driver)
- 解决error:2014 Commands out of sync; you can't run this command now