文章大綱
一、Android崩潰日志管理簡(jiǎn)介
二、崩潰日志管理實(shí)戰(zhàn)
三、項(xiàng)目源碼下載
一、Android崩潰日志管理簡(jiǎn)介
1. 什么是android崩潰日志管理
??開發(fā)中有些地方未注意可能造成異常拋出未能caught到,然后彈出系統(tǒng)對(duì)話框強(qiáng)制退出。這種交互不好,而且開發(fā)者也不能及時(shí)獲取到底哪里出問題。因此我們可以使用android的UncaughtExceptionHandler來處理這種異常。
2. 操作邏輯
用戶端(出現(xiàn)崩潰)
??我們會(huì)封裝一個(gè)通用的jar包,該jar包包括日志打印、捕獲異常信息邏輯、網(wǎng)絡(luò)傳輸、設(shè)置Debug和Release模式、獲取本機(jī)的相關(guān)信息等,當(dāng)出現(xiàn)異常時(shí),將異常信息以文件方式保存在用戶手機(jī)中,并且發(fā)送到后臺(tái),當(dāng)后臺(tái)接收成功時(shí),自動(dòng)刪除用戶手機(jī)的崩潰信息文件,若接收失敗,在下次發(fā)生崩潰時(shí),將歷史發(fā)送失敗的崩潰一同發(fā)送。
接收端(后臺(tái))
??我們會(huì)編寫一個(gè)地址,用于接收異常的具體信息,并儲(chǔ)存在本地文件中,以此作為日志進(jìn)行管理。
二、崩潰日志管理實(shí)戰(zhàn)
1. 后臺(tái)端
??在該實(shí)戰(zhàn)中,我以簡(jiǎn)單的servlet進(jìn)行講解,實(shí)際項(xiàng)目中,可以以ssm或spring boot等框架進(jìn)行操作。
2. 客戶端通用項(xiàng)目
網(wǎng)絡(luò)請(qǐng)求相關(guān)的配置管理類:HttpManager.java
文件上傳相關(guān)類:UploadLogManager.java
package com.qihoo.linker.logcollector.upload;
import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;
import com.qihoo.linker.logcollector.capture.LogFileStorage;
import android.content.Context;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
客戶端崩潰日志文件的刪除,保存等操作類:LogFileStorage.java
文件保存在Android/data/包名/Log/下
package com.qihoo.linker.logcollector.capture;
import java.io.File;
import java.io.FileOutputStream;
import com.qihoo.linker.logcollector.utils.LogCollectorUtility;
import com.qihoo.linker.logcollector.utils.LogHelper;
import android.content.Context;
import android.util.Log;
UncaughtExceptionHandler實(shí)現(xiàn)類:CrashHandler.java
??當(dāng)出現(xiàn)異常時(shí),會(huì)進(jìn)入public void uncaughtException(Thread thread, Throwable ex) 方法中。
項(xiàng)目調(diào)用封裝類:LogCollector.java
3. 客戶端接入使用
為通用項(xiàng)目設(shè)置is Library模式
實(shí)際android項(xiàng)目使用
添加Library
在Application子類中進(jìn)行初始化
public class MyApplication extends Application {
編寫異常并上傳異常
public class MainActivity extends Activity implements OnClickListener {
private Button btn_crash;
private Button btn_upload;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_crash = (Button) findViewById(R.id.button1);
btn_upload = (Button) findViewById(R.id.button2);
btn_crash.setOnClickListener(this);
btn_upload.setOnClickListener(this);
}
運(yùn)行結(jié)果如下圖所示
--No1Qr4Tu7Wx
content-disposition: form-data; name="logfile"; filename="c5c63fec3651fdebdd411582793fa40c.log"
Content-Type: application/octet-stream; charset=utf-8
&start---
logTime:2019-04-07 10:54:47
appVerName:1.0
appVerCode:1
OsVer:5.1.1
vendor:samsung
model:SM-G955F
mid:c5c63fec3651fdebdd411582793fa40c
exception:java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String[] java.lang.String.split(java.lang.String)' on a null object reference
crashMD5:74861b8fb97ef57b82a87a826ab6b08f
crashDump:{java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String[] java.lang.String.split(java.lang.String)' on a null object reference
at com.jiabin.logcollectorexample.MainActivity.causeCrash(MainActivity.java:32)
at com.jiabin.logcollectorexample.MainActivity.onClick(MainActivity.java:45)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5293)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
}
&end---
--No1Qr4Tu7Wx--