关于拔出SDCARD或U盘后apk关闭的问题
2014-11-14 09:16
986 查看
当apk读取sdcard中的文件时,sdcard被拔出。apk读取的文件消失,系统将给apk抛出io异常。如果apk未对异常做出正确的处理,apk将被强制关闭。怎样才是正确的处理呢?
当apk收到io异常后,apk应当迅速停止操作文件,并对关闭文件句柄。为什么不这么操作apk就被强制关闭呢?
这是系统逻辑,具体原因是:
sdcard拔出后,android系统的vold将接收到来自系统的uevent事件,vold读取事件相关的信息,获知是sdcard拔出后,尝试执行umount sdcard的操作,但因为sdcard中的文件被apk打开,此时无法执行umount操作,在多次尝试后,apk未能停止文件操作并关闭文件,vold将强制发生SIG_KILL信号关闭apk,这就造成了apk停止运行。
具体源码分析:
/system/vold/main.cpp main函数中
volumemanager在收到sdcard拔出的事件后,执行doUnmount操作
当apk收到io异常后,apk应当迅速停止操作文件,并对关闭文件句柄。为什么不这么操作apk就被强制关闭呢?
这是系统逻辑,具体原因是:
sdcard拔出后,android系统的vold将接收到来自系统的uevent事件,vold读取事件相关的信息,获知是sdcard拔出后,尝试执行umount sdcard的操作,但因为sdcard中的文件被apk打开,此时无法执行umount操作,在多次尝试后,apk未能停止文件操作并关闭文件,vold将强制发生SIG_KILL信号关闭apk,这就造成了apk停止运行。
具体源码分析:
/system/vold/main.cpp main函数中
/* Create our singleton managers */ if (!(vm = VolumeManager::Instance())) { SLOGE("Unable to create VolumeManager"); exit(1); }; if (!(nm = NetlinkManager::Instance())) { SLOGE("Unable to create NetlinkManager"); exit(1); }; if (!(dpl = DevPathListen::Instance())) { SLOGE("Unable to create DevPathListen"); exit(1); };这里创建VolumeManager负责主要是用来管理usb/sd卡等外部存储设备,NetlinkManager负责接收系统内核的uevent事件,并告知volumemanager。
volumemanager在收到sdcard拔出的事件后,执行doUnmount操作
int Volume::doUnmount(const char *path, bool force) { int retries = 10; if (mDebug) { SLOGD("Unmounting {%s}, force = %d", path, force); } while (retries--) { if (!umount(path) || errno == EINVAL || errno == ENOENT) { SLOGI("%s sucessfully unmounted", path); return 0; } int action = 0; if (force) { if (retries == 1) { action = 2; // SIGKILL } else if (retries == 2) { action = 1; // SIGHUP } } SLOGW("Failed to unmount %s (%s, retries %d, action %d)", path, strerror(errno), retries, action); Process::killProcessesWithOpenFiles(path, action); usleep(1000*1000); } errno = EBUSY; SLOGE("Giving up on unmount %s (%s)", path, strerror(errno)); return -1; }doUnmount尝试unmount,不成功则执行
killProcessesWithOpenFiles
killProcessesWithOpenFiles是获取哪些进程打开了sdcard中文件,并根据action,发送SIG_KILL或SIG_HUP给相关进程。 unumount尝试8次后,action被设置为1,则发送SIG_KILL,杀掉apk。 为防止apk在sdcard拔出时停止运行,apk在收到io异常后,应及时关闭文件句柄。 关于android中vold系统的详细分析可以参考<<android系统vold透析>>
相关文章推荐
- 解决linux自动挂载U盘/SD Card变成只读问题
- 关于通过DDMS向Android系统的模拟器的sdcard中导入mp3文件的问题
- 解决linux自动挂载U盘/SD Card变成只读问题
- 关于Android SDCard存储的问题
- (转)解决Ubuntu自动挂载U盘/SD Card变成只读问题
- 关于android sqlite database存储到sdcard上的问题
- 关于被安装到sdcard,无法接受到系统启动事件的问题, 修改安装路径
- 解决APP在线更新时用户没有sdcard而产生的APK下载路径问题
- 关于android读写sdcard的权限问题
- android 从sdcard安装apk,点击home键,出现问题
- 控制台ADB 命令安装apk到手机sdcard及安装qq过程中问题:: to '/sdcard/tmp/': Is a directory解决
- 关于mnt/sdcard一直不能写入的问题
- 关于通过DDMS向Android系统的模拟器的sdcard中导入mp3文件的问题
- 关于如何关闭PXE网络启动模块的问题
- 关于Web程序打开Word、Excel后,不能关闭的问题的一个解决办法
- 双击运行Android模拟器、创建SDcard、AVD、安装APK文件、上传文件到模拟器
- 关于客户端关闭cookie,session是否能继续使用的问题?php
- 安装APK文件到Android模拟器和Android sdcard的使用
- android sdcard 写入数据权限的问题
- 关于关闭浏览器后清除session的问题