您的位置:首页 > 其它

关于Usb直接拔出导致的进程崩溃问题

2015-03-03 15:01 2226 查看
【转载请保存链接,谢谢合作】------http://blog.csdn.net/qq_21972057/article/details/44038313

说在前面的话,可能会说的比较啰嗦,啰嗦是因为走得路太啰嗦..勿喷....

最近遇到一个不大不小的坑,我这边是做android机顶盒,有一个功能是做在识别U盘的内容,包括apk,音视频,图片等。不怎么暴力的测试小伙伴在拔出U盘的物理动作是,会概率性报错,(由于需求里面有获取apk的icon并且显示出来的功能),具体log如下:

<span style="font-family:Microsoft YaHei;">02-12 16:37:26.686 D/Vold    (  126): Volume sda1 state changing 4 (Mounted) -> 5 (Unmounting)
02-12 16:37:26.686 D/MountService(  476): sendStorageIntent Intent { act=android.intent.action.MEDIA_EJECT dat=file:///storage/external_storage/sda1 (has extras) } to UserHandle{-1}
02-12 16:37:27.686 D/Vold    (  126): Volume::unmountVol partitions=0x80000000 type=3
02-12 16:37:27.686 W/Vold    (  126): Failed to unmount /storage/external_storage/sda1 (Device or resource busy, retries 2, action 1)
02-12 16:37:27.836 E/ProcessKiller(  126): Process com.xx.xxx.xxxxx (771) has open file /storage/external_storage/sda1/antutu-benchmark-v560.apk
02-12 16:37:27.836 W/ProcessKiller(  126): Sending SIGHUP to process 771
02-12 16:37:27.956 I/ActivityManager(  476): Process com.xx.xxx.xxxxx (pid 771) has died.</span>


分析核心点,是因为Fail to unmount...

在自己无头苍蝇一天后,求助了系统层小伙伴,得到答复大概意思是说,资源被占用,并且给了我2个思路去处理这个问题

1.屏蔽信号 sighup,kill信号,自己接受信号并且自己来处理,默认情况下,接受了该信号,就会kill掉调用他的进程

2.找到还有哪里占用资源的地方,统统释放掉。

我第一时间还是按照方案2去解决的,毕竟另一个实在不熟...

所以对于占用资源,我是这么想的

1.adapter内当时取了这个apk的icon,可能在拔出U盘的时候还在持续引用的,处理之;

2.adapter内可能还取这个apk的名字等基本信息,处理之;

3.adapter和listview等一切可能导致资源被拉住的,处理之;

在我折腾一番发现,的确有好转,在我比较兴奋准备收拾东西下班的时候,娘的又崩了!log依旧如上!

崩溃之余,尝试方案1.

系统层小伙伴在修改了vold类以后,当接受到这个信号以后不去进行处理kill的指令,或者屏蔽了我们项目的进程,可以达到效果,但是为了可移植性,还是建议我去想其他方案,思路如下:

1.写JNI去重写该信号,自己接管这个信号,不去做kill的指令

2.从java层找如上的方案,接管信号

自然先去找java层的屏蔽的方案,路子也很多,链接也很多

【感兴趣的可以查看该链接--------->blog.csdn.net/kevinzhangfei/article/details/6997110】

代码很简单,思路很明确,所以坑的也很惨。

这tm都是毛啊!!!!

继续度娘一天以后,原来是jdk里面的一个jar,复制-build-找到类了,nice! 开始编译! 卡死 。重启,开始编译!卡死.....

然后仔细研究发现这坑爹的jar,居然接近60M

【该jar在JDK1.7_32bit\jre\lib下,感兴趣的同学可以研究下】

接着 改eclipse内存,各种改,依旧build不起来,各种oom.

然后尝试着说把这个jar精简,据说bese64加密的导入包也是rt.jar里面的,精简以后大约100K以内,so 尝试着精简jar的道路,进了另一个坑。

【感兴趣的小伙伴可以查看该链接---->http://download.csdn.net/detail/pzhtpf/3878285 据说很强大】

他的原理是把所有的功能使用一遍,然后会保留这些类在rt.jar里面的引用,然后只保留这些class,达到最简效果。听起来是不是高大上!

可是他妹的我都build不起来啊,如何使用“所有功能”!!

又一天过去以后,还是回归了原点,还是想从源头处理关于引用被占用导致不能unmount的问题......

由于需求里面有获取apk的icon并且显示出来的功能,当时网上一搜一大把的【获取未安装apk的icon】的帖子一抓一大把

之前我是采用反射去做 【--------->链接在这里  http://blog.sina.com.cn/s/blog_4d25c9870100rmwy.html】

系统层小伙伴提醒我通过反射写还是不易于控制是否关闭该关闭的东西,还是很庆幸找到了可以不通过反射调用的方法,内容如下

<span style="font-family:Microsoft YaHei;"><span style="font-size:14px;">/**
* 获取未安装apk的Icon和相关信息
*
* @param ctx
* @param bean
* @param archiveFilePath
* @return
*/
public static Drawable getUninstallAPKInfo(Context ctx, String archiveFilePath) {

String appName = null;
String pakName = null;
PackageManager pm = ctx.getPackageManager();
PackageInfo pakinfo = pm.getPackageArchiveInfo(archiveFilePath, PackageManager.GET_ACTIVITIES);

Drawable icon;
if (pakinfo != null) {

ApplicationInfo appinfo = pakinfo.applicationInfo;

appinfo.sourceDir = archiveFilePath;
appinfo.publicSourceDir = archiveFilePath;
icon = appinfo.loadIcon(pm);

appName = (String) pm.getApplicationLabel(appinfo);
pakName = appinfo.packageName;

} else {
icon = null;

}
return icon;
}</span></span>


系统层小伙伴还是建议我从这里下手,说不定里面有未释放的调用对象

尝试性的做了下处理

将涉及到3个对象都做了简单的制空......

竟然出奇般的不崩了......再也没有发出过Unmount的信号...至少我自己是测试不出来了.....

突然没那么兴奋了,就tm这么一个制空就可以???并且想起来为什么总崩溃的是apk,从来没有报错过u盘内的图片资源被占用呢?

然后看了下,关于imageview在setDrawble后,在最后,还是close掉了流..(截图找不到鸟...找到补上!)

然后系统层小伙伴说像那样在播放中的音频文件,视频文件,你物理拔掉U盘以后,他们是会有对这些信号自行做接管的,也就更容易理解了这些小细节,当然我自己没有去调研更深,仅是小伙伴跟我描述,所以遇到较真的大神,请轻喷。

稍微告一段落,写的啰啰嗦嗦,不过还是涨了不少各种姿势,如果有大神有新的思路和问题,欢迎指出。

写在最后的话,如上方式,我在现有情况下是没有测试出来崩溃,如果新的问题,我会补充更新。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐