Android Crash收集

這個崩潰日志的收集個人感覺還是很不錯的喷鸽,因為你可以通過這里面發(fā)現(xiàn)一些意想不到的Crash部脚。

基本沒什么步驟:

創(chuàng)建一個crash收集類(Crash.java)

/**
 * Created by DaFengA on 2017/11/18.
 */

public class Crash implements Thread.UncaughtExceptionHandler{

   private Context mContext;
   public Crash(Context context) {
        Thread.setDefaultUncaughtExceptionHandler(this);
        mContext = context;
    }
  /**
     * @param thread    當(dāng)前線程
     * @param throwable 異常信息
     */
    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {

    }
}

2個要點译秦,一是讓Crash類實現(xiàn)UncaughtExceptionHandler远搪,再實現(xiàn)方法 uncaughtException();
二是在構(gòu)造方法中寫入 Thread.setDefaultUncaughtExceptionHandler(this) 只有走了這句劣纲,系統(tǒng)才會把crash交給你處理,而處理的場所就是uncaughtException()谁鳍,越早走越好味廊,否則在這句代碼之前的錯誤就收集不到了,所以把他放在Application中棠耕。

public class BaseApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        new Crash(this);
    }
}

現(xiàn)在App中的錯誤余佛,系統(tǒng)已經(jīng)交給了你的處理類處理了。


放張圖:

系統(tǒng)處理Crash.jpg

這個是大部分系統(tǒng)處理Crash的情況窍荧,直接關(guān)掉app辉巡;但是MIUI不一樣,他會重啟錯誤Activity的前一個Activity蕊退,如果當(dāng)前Activity棧只有錯誤的Activity這一個實例郊楣,才會退出App(沒有Activity可以退的了)

當(dāng)然你已經(jīng)把系統(tǒng)要處理的東西接盤了瓤荔,所以就不會有上述的差異了净蚤,說說uncaughtException()方法中寫什么

保存錯誤到本地是肯定的,給出代碼:

 @Override
 public void uncaughtException(Thread thread, final Throwable throwable) {
     //給用戶提示
     new Thread() {
         @Override
         public void run() {
             //只有主線程是有消息隊列的输硝,要調(diào)用Looper.prepare()給子線程創(chuàng)建消息隊列今瀑,再通過Looper.loop()來使消息隊列起作用。
             Looper.prepare();
             Toast.makeText(mContext, "出現(xiàn)錯誤,請稍后再試!", Toast.LENGTH_SHORT).show();
             Looper.loop();
         }
     }.start();
     //檢查讀寫權(quán)限
     if (PermissionsCheck.getInstance(mContext).lacksPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}) != null) {
         //退出App
         SystemClock.sleep(2000);
         return;
     }
     //判斷SD卡的狀態(tài)  MEDIA_MOUNTED表示正常
     if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
         //退出App
         SystemClock.sleep(2000);
         return;
     }
     //保存錯誤信息到本地
     new Thread(){
         @Override
         public void run() {
             try {
                 //創(chuàng)建文件夾
                 File folder = new File( Environment.getExternalStorageDirectory().getPath() + "/DaFenga/");
                 //判斷文件是否存在
                 if (!folder.exists()) {
                     //創(chuàng)建包括父目錄的目錄
                     folder.mkdirs();
                 }
                 //獲取當(dāng)前時間
                 long current = System.currentTimeMillis();
                 final String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(current));
                 //創(chuàng)建file
                 File file = new File(Environment.getExternalStorageDirectory().getPath() + "/DaFenga/" + "crash" + ".ttt");
                 PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file, true)));
                 //保存手機信息和異常信息
                 PackageManager pm = mContext.getPackageManager();
                 PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
                 pw.println("異常時間:" + time);
                 pw.println("app版本:" + pi.versionName);
                 pw.println("app版本號:" + pi.versionCode);
                 pw.println("Android版本:" + Build.VERSION.RELEASE);
                 pw.println("SDK版本:" + Build.VERSION.SDK_INT);
                 pw.println("制造商:" + Build.MANUFACTURER);
                 pw.println("型號:" + Build.MODEL);
                 pw.println("版本號:" + Build.DISPLAY);
                 pw.println("唯一識別碼:" + Build.FINGERPRINT);
                 pw.println("異常信息:");throwable.printStackTrace(pw);
                 if (pw != null) {
                     pw.close();
                 }
             } catch (Exception e) {
                 e.printStackTrace();
                 Log.e("Crash", "Exception: " + e.getMessage());
             }
         }
     }.start();
     //等待一段時間点把,退出APP橘荠。
     SystemClock.sleep(2000);
 }

給用戶提示,我用的Toast,因為代碼中的mContext是在Applaction中取得的郎逃,想用Dialog就必須要有依附的activity哥童,所以不可以。用Looper的原因注釋中已給出褒翰。

注釋很全贮懈,這里我保存的路徑是

//根目錄下的DaFenga文件夾中的crash.ttt文件
Environment.getExternalStorageDirectory().getPath() + "/DaFenga/" + "crash" + ".ttt"

錯誤文件位置.jpg

把.ttt改成.txt打開看看:


錯誤詳情.jpg

這個錯誤日志的上傳,就看個人處理了优训。

還需要注意的一點朵你,上面代碼中的退出App我沒有寫,這個最穩(wěn)妥的方法是自己寫一個工具類型宙,記錄打開的activity撬呢,退出的時候,遍歷記錄的activity關(guān)掉妆兑。實測什么系統(tǒng)退出魂拦,殺進(jìn)程都會出現(xiàn)不能完全退出的情況

//系統(tǒng)退出
System.exit(0);
//殺進(jìn)程
Process.killProcess(android.os.Process.myPid());

給一個退出App的工具類:

/**
 * Created by DaFengA on 2017/7/21.
 *
 */

public class FinishApp extends Application {
    private Map<String, Activity> activityMap = new HashMap<String, Activity>();
    private static volatile FinishApp instance;

    private FinishApp() {
    }

    // 單例模式
    public static FinishApp getInstance() {
        if (null == instance) {
            synchronized (FinishApp.class) {
                if (instance == null) {
                    instance = new FinishApp();
                }
            }
        }
        return instance;
    }

    // 將Activity添加到容器中
    public void addActivity(Activity activity) {
        activityMap.put(activity.getLocalClassName(), activity);
    }

    // 將Activity添加到容器中
    public void removeActivity(Activity activity) {
        activityMap.remove(activity.getLocalClassName());
    }

    // 當(dāng)要退出Activity時毛仪,遍歷所有Activity 并finish
    public void exit() {
        for (Map.Entry<String, Activity> entry : activityMap.entrySet()) {
            entry.getValue().finish();
        }
        activityMap.clear();
        System.exit(0);
    }
}

麻煩的就是每個activity的onCreate中添加FinishApp.getInstance().addActivity(this);,onDestroy中移除FinishApp.getInstance().removeActivity(this);都要寫芯勘。退出調(diào)用FinishApp.getInstance().exit();




對于生活理想箱靴,應(yīng)該像宗教徒對待宗教一樣充滿虔誠與熱情!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荷愕,一起剝皮案震驚了整個濱河市衡怀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌安疗,老刑警劉巖抛杨,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異荐类,居然都是意外死亡怖现,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門玉罐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來屈嗤,“玉大人,你說我怎么就攤上這事吊输∪暮牛” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵季蚂,是天一觀的道長茫船。 經(jīng)常有香客問我,道長癣蟋,這世上最難降的妖魔是什么透硝? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任狰闪,我火速辦了婚禮疯搅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘埋泵。我一直安慰自己幔欧,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布丽声。 她就那樣靜靜地躺著礁蔗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪雁社。 梳的紋絲不亂的頭發(fā)上浴井,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機與錄音霉撵,去河邊找鬼磺浙。 笑死洪囤,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的撕氧。 我是一名探鬼主播瘤缩,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼伦泥!你這毒婦竟也來了剥啤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤不脯,失蹤者是張志新(化名)和其女友劉穎府怯,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體防楷,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡富腊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了域帐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赘被。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖肖揣,靈堂內(nèi)的尸體忽然破棺而出民假,到底是詐尸還是另有隱情,我是刑警寧澤龙优,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布羊异,位于F島的核電站,受9級特大地震影響彤断,放射性物質(zhì)發(fā)生泄漏野舶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一宰衙、第九天 我趴在偏房一處隱蔽的房頂上張望平道。 院中可真熱鬧,春花似錦供炼、人聲如沸一屋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冀墨。三九已至,卻和暖如春涛贯,著一層夾襖步出監(jiān)牢的瞬間诽嘉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留虫腋,地道東北人身冬。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像岔乔,于是被迫代替她去往敵國和親酥筝。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,075評論 25 707
  • 1 什么是Crash Crash雏门,即閃退嘿歌,多指在移動設(shè)備(如iOS、Android設(shè)備)中茁影,在打開應(yīng)用程序時出現(xiàn)的...
    天才木木閱讀 55,746評論 37 281
  • 秋雨綿綿的日子來了宙帝,冒雨去買了菜回來。心疼那些披著塑料薄膜賣菜的老人們募闲。 最近總是做著各種奇奇怪怪的夢步脓,是太閑了吧...
    幺姑娘啊閱讀 157評論 0 0
  • 在誠毅學(xué)院的教學(xué)區(qū)和宿舍區(qū)之間,連綴著一條長約300米的碑廊浩螺,紅柱綠瓦靴患,古樸典雅,共收錄了陳嘉庚先生的重要語錄80...
    蘇念和閱讀 488評論 0 3
  • 一天一天推翻自己堅持的信仰要出,我會記住自己今天的模樣鸳君。――《給未來的自己》 今天是師大又一年的新生運動會,我的思緒不...
    forever林杰閱讀 447評論 0 1