人的大脑分为L型和R型部分,L型是线性的,R型是非线性的。L型是逻辑的体现,R型是灵感的来源。当人在处理问题的时候,大部分的情况下是使用L型大脑,基于以下的过程:
根据基本的证据,提出一个或多个假设,如果问题较为复杂,则需要分阶段解决,先提出第一阶段的假设,判断假设是否正确,如果证据不够,则为之搜集证据。假设通过之后,作为新的证据,和之前的证据一起分析,提出下一阶段的假设或者简单问题的解决方案。
这个循环,在求解数学问题的时候尤其关键。大家都有体会。而程序要解决的问题,也都是需要经过类似的循环。但是这个过程可能会存在混乱和陷阱,可能得到错误的答案或者得不到答案。通过对一个最近解决的问题的过程的反思,来看看我们都会犯什么错误。
问题:
写一个android程序,判断android手机是否有插SD卡。这个问题本来很简单,
1 boolean isSomethingMounted = android.os.Environment 2 .getExternalStorageState().equals( 3 android.os.Environment.MEDIA_MOUNTED);
但是由于部分三星手机有所谓内置的USB存储器,即使没有插SD卡的情况下,这个判断的结果仍然会是true。
我是怎么一步一步找到答案的——而且是错误的答案。
先搜集资料,网上搜索后,有人讨论过这个问题,提到三星的外部SD卡将会挂载在/sdcard/external_sd目录下,而不是/sdcard。自己试了一下,的确如此,而且/sdcard的目录下有:
/sdcard/usbStorage
/sdcard/external_sd
(PS:/sdcard是链接向/mnt/sdcard。后文的/mnt/sdcard/...的描述和/sdcard/...等价)
不管有没有插SD卡,上面两个目录都会存在。但是在没有插SD的情况下为空目录,插了SD的情况下则是SD卡的目录。
我认为,在没有插入SD卡的情况下,/sdcard/external_sd目录虽然存在,但应该是不可写的。于是写出了这样的判断程序:
是否有"/mnt/sdcard/external_sd"目录存在,如果有,则SD卡是需要挂载到这里的,那么检查是否canWrite,如果是,才认为有安装SD卡。
但是经过测试发现,这个判断没有起到作用。没有插SD的情况下,/sdcard/external_sd也是可写的。
在有插SD卡的情况下:
这证明了我对于external_sd会链接向不同目录的判断。再看没有SD卡的输出,/sdcard和/sdcard/external_sd,/sdcard/usbStorage的输出是一样的。于是我认为,这三个目录其实都是同一个目录。而在插入SD卡后,/external_sd将指向一个不同的目录。
于是我想出了这样的判断:
如果external_sd和usbStorage是同一个目录,则没有插入SD卡;否则有插入SD卡。
由于不能执行"ls -al"命令,所以,我写程序的时候,想出这种方式:
在/external_sd上创建一个临时文件,如果这个临时文件也在usbStorage下出现,那么它们是相同的目录,否则它们不是。
但是运行结果不正确。通过adb shell命令试验,发现即使没有插SD卡,external_sd目录下创建的文件也不会出现在usbStorage目录下。它们不是相同目录。
于是,我决定换一个思路。android手机在插入SD卡的时候,会启动扫描过程。而这个扫描过程应该会在SD卡上留下一些缓存文件。所以可以根据external_sd目录下是否有这些和这个扫描过程相关的文件来判断它是否一个SD卡目录。
正当我在搜集和android的媒体扫描过程相关的资料的时候,一个前辈和我讨论了这个问题。他对LINUX比较熟。他敲入了"df"命令,在插入SD卡情况下,会出现/mnt/sdcard和/mnt/sdcard/external_sd这两个挂载点,而没有插入SD卡情况下,只有前者。
受到启发,我写出了这样的判断程序:
在external_sd存在的情况下,使用"df"判断是否有/mnt/sdcard/external_sd这个挂载点。如果有,则有SD卡,否则没有。
测试通过。
令我忧虑的是,如果没有这个前辈,我可能最终得到的是一个错误的解,就是根据android的媒体扫描来判断,也许它能够工作,但是它不是一个接近问题本质的解,我还可能最终得不到解,而放弃这个问题。
所以,有没有办法建立一个分析过程,在没有这个前辈的情况下,我最终也得到了问题的最优解?