13、主線程任務太多導致異常退出(The application may be doing too much work on its main thread)


今天花費了一天的時間來解決這個bug。

這種在程序運行期間出現的問題比較棘手,如果再沒有規律的話就更難解決。

還好這個bug是由規律的,也就是說在程序執行半個小時左右后就會因為此異常而導致程序退出;那么在網上找了下原因,無非是說一下幾點:

1、把業務放在子線程中去完成,然后通過handler來更新界面

2、通過runOnUiThread的方法來實現

再補充一點就是:優化代碼,將不需要重復執行的代碼執行一次就ok了,特別是需要繪制UI的代碼更不能隨便放在重復執行的地方

 

 

 

一、bug現場還原

我的程序就是類似一個會自動播放圖片的網絡圖片瀏覽器

通過定時器來每隔10s去執行一次圖片的網絡請求,得到圖片后設置為imagview將要顯示的圖片;通過這兩步基本就完成基本需求了。

但是當程序在運行30分鍾,也就是播放了100多張不同的照片后,出現了“Skipped 62 frames!  The application may be doing too much work on its main thread”這樣的bug,同時還伴隨“GC_FOR_ALLOC freed 2755K, 18% free 13874K/16884K, paused 3753ms, total 3756ms”這樣的錯誤

 

二、bug出現的原因

從報出的異常本身來說,意思就是主線程任務太重,內存耗用太多。但是我用的是BitmapUtils這個工具庫,只有第一次會進行網絡請求,之后就會用默認的緩存數據

所以說問題肯定不在網絡請求數據這塊,那就是在imageVIew設置圖片資源這里。

仔細看看,不應該有問題啊,就這幾個代碼:

1 linearParams = new RelativeLayout.LayoutParams(
2                         CommonUtils.getScreenWidth(contextShowCall), CommonUtils.getScreenHeight(contextShowCall));
3 imageView.setLayoutParams(linearParams);
4 String imgUrl = "http://"+QiNiuBucketName+".com1.z0.glb.clouddn.com/image-"+pic_casted_index+".jpg"; 5 6 relativeLayoutShowCall.setBackgroundDrawable(new BitmapDrawable(lastBitMap)); 7 bitmapUtils.display(imageView, imgUrl, bigPicDisplayConfig, callback);

從代碼上來看,前3行的代碼,在imageView在程序其他地方沒有對其修改的前提下,是不用重復設置的。將前三行代碼放到程序初始化的地方,再運行程序后,發現運行2小時內暫時未發現問題。

問題鎖定在了這3行代碼:重復從內存中申請變量,重復設置控件的寬度和高度,再加上必須得重繪圖片,對於主線程來說確實任務較重,那么通過將調整代碼后確實減輕了主線程的任務量(只是重繪imageView的圖片就可以了)。

 

總結:

1、對於在程序運行期間出現的bug,要尋找規律,尋找規律的方法之一就是在多個設備同時執行同一程序,進而快速定位錯誤出現的時間點和錯誤日志

2、最好是在程序異常時能夠保證100%將異常數據發送到開發者郵箱或者管理工具,很抱歉,我還沒找到一款能符合條件的(國外的mint splunk、國內的友盟都做不到100%)

3、eclipse的logcat默認只可以緩存5000條數據,可以這樣設置,從而方便查看系統log:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM