強制拔SDCard,App爲啥會概率性crash?

異常狀態:

錄video時強制拔出SDCard,video出現兩種狀態:1.Force Close  2.未保存返回到Preview界面

===Force close===
10-16 15:32:32.794 I/CAM_VideoModule(22145): MMMstopabove
10-16 15:32:33.482 V/CAM_VideoModule(22145): stopVideoRecording: Setting current video filename: /storage/sdcard1/DCIM/Camera/VID_20151016_153226.mp4.tmp
10-16 15:32:33.482 I/CAM_VideoModule(22145): SavingThread finally
10-16 15:32:33.482 I/CAM_VideoModule(22145): lina mVideoFileDescriptor == null

===Return to Preview===
10-16 15:29:49.304 I/CAM_VideoModule(21338): MMMstopabove
10-16 15:29:49.906 V/CAM_VideoModule(21338): stopVideoRecording: Setting current video filename: /storage/sdcard1/DCIM/Camera/VID_20151016_152934.mp4.tmp
10-16 15:29:49.906 I/CAM_VideoModule(21338): SavingThread finally
10-16 15:29:49.907 I/CAM_VideoModule(21338): lina mVideoFileDescriptor == null
10-16 15:29:50.145 D/CAM_VideoModule(21338): saveVideo duration :14869
10-16 15:29:50.146 V/CAM_VideoModule(21338): Releasing media recorder.
10-16 15:29:50.173 W/CAM_VideoModule(21338): onPauseBeforeSuper
10-16 15:29:50.173 W/CAM_VideoModule(21338): closeCamera
10-16 15:29:50.238 W/CAM_VideoModule(21338): closeCamera() normal video,should change to photo!
10-16 15:29:50.238 V/CAM_VideoModule(21338): Releasing media recorder.


對照Log查看VideoModule.java代碼,發現如下調用順序
stopVideoRecording()->saveOnStopVideoRecording()->videoHasStoped(fail)->saveVideo()

FC就發生在saveVideo()函數中。

於是查看saveVideo()

private void saveVideo() {
        if (mVideoFileDescriptor == null) {
            long duration = SystemClock.uptimeMillis() - mRecordingStartTime;

            // [BUGFIX]-Add by TCTNB,haibo.chen, 2014-10-24,PR812550 Begin
            // Duration will be obtained first from decoder information to
            // avoid any errors about calculation.
            MediaPlayer mediaPlayer = new MediaPlayer();
            try {
                mediaPlayer.setDataSource(mCurrentVideoFilename);
                mediaPlayer.prepare();
                duration = mediaPlayer.getDuration();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                mediaPlayer.release();
                mediaPlayer = null;
            }
            Log.d(TAG, "saveVideo duration :" + duration);
            // [BUGFIX]-Add by TCTNB,haibo.chen, 2014-10-24,PR812550 End
            ……
}

發生FC的情況就沒有走到紅色Log處。就Crash退出啦。
10-16 16:45:12.862 W/ActivityManager(  834): Killing processes unmount media at adjustment 0
10-16 16:45:12.862 I/ActivityManager(  834): Killing 29369:android.process.media/u0a8 (adj 0): unmount media
10-16 16:45:12.899 W/ActivityManager(  834): Scheduling restart of crashed service com.android.providers.media/.MediaScannerService in 24702ms
10-16 16:45:12.899 I/ActivityManager(  834): Killing 29749:com.tct.camera/u0a154 (adj 0): depends on provider com.android.providers.media/.MediaProvider in dying proc android.process.media

MediaScannerService:  安卓系統會在後臺掃描內存和外存設備,將多媒體數據更新到數據庫中。同時也會掃描文件的信息。
MediaProvider: 在項目中你就可以通過ContentProvider查詢數據庫,獲取存取卡里的多媒體信息。

每次開機的時候系統會先掃描sdcard,sdcard重新插拔(掛載)也會掃描一次sdcard。爲什麼要掃描sdcard,其實是爲了給系統的其他應用提供便利,比如,Gallary、Music、VideoPlayer等應用,進入Gallary後會顯示sdcard中的所有圖片,如果進入Gallary後再去掃描,可想而知,你會厭惡這個應用,因爲我們會覺得它反應太慢了。還有Music你看到播放列表的時候實際能看到這首歌曲的時長、演唱者、專輯等信息,這個也不是你進入應用後一下子可以讀出來的。所以Android使用sdcard掛載後掃描的機制,先將這些媒體相關的信息掃描出來保存在數據庫中,當打開應用的時候直接去數據庫讀取(或者所通過MediaProvider去從數據庫讀取)並show給用戶,這樣用戶體驗會好很多。

爲什麼有時候會crash,有時候不會呢?

剛剛插入SDCard的幾秒鐘內,系統還在掃描sdcard呢!你突然拔出,後面調用MediaProvider時,自然會crash啊。
人家食物都沒有準備好,你就要吃啦。沒食物可吃,所以就死啦。
據此分析,如果延遲幾秒鐘拔出SDCard,待掃描完成,再強制拔出,則Camera不會crash。







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章