CrashHandler를 사용하여 어플리케이션에 대한 crash 정보를 얻습니다.
8081 단어 Android
2. Android는 이러한 문제를 처리하는 방법을 제공합니다.Thread 클래스의 방법 setDefaultUncaughtExceptionHandler ().이 방법은 시스템의 기본 이상 프로세서를 설정할 수 있습니다.crash가 발생하면 시스템은 UncaughtExceptionHandler의 uncaughtException 방법을 리셋하여 uncaughtException 방법에서 이상 정보를 얻을 수 있다(코드에서 포착된 이상은 CrashHandler에 처리하지 않는다). 이상 정보를 SD카드에 저장하고 적당한 시기에 네트워크를 통해 crash 정보를 서버에 업로드할 수 있다.이렇게 하면 개발자는 사용자crash의 장면을 분석하여 다음 버전에서 이런crash를 복원할 수 있다.
3. 위의 분석을 통해 알 수 있듯이 응용된crash의 정보를 얻는 방식은 먼저 UncaughtExceptionHandler 대상을 실현하고 그의 uncaughtException 방법에서 이상 정보를 얻어SD카드에 저장한다(적당한 시기에 서버에 올려 개발자가 분석할 수 있도록 한다).그리고 Thread의 setDefaultUncaughtExceptionHandler () 를 호출하여 루트 기본 이상 프로세서 (Application이 초기화될 때 프로그램에 CrashHandler를 설정할 수 있음) 를 설정합니다. 기본 라이브러리 프로세서를 사용할 때 Thread 클래스의 정적 구성원이기 때문에 대상을 사용할 때 현재 프로세스의 모든 루트입니다.
4.다음은 내가 스스로 실현한 이상 프로세서이다.
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* Created by zb.yang on 2017/12/22.
*/
public class ZbCrashHandler implements Thread.UncaughtExceptionHandler {
private static final String TAG = "ZbCrashHandler";
private static final String PATH = Environment.getExternalStorageDirectory().getPath()+"/CrashHandler/log";
private static final String FILE_NAME = "crash";
private static final String FILE_NAME_SUFFIX = ".trace";
// UncaughtException
private Thread.UncaughtExceptionHandler mDefaultHandler;
//CrashHandler
private static ZbCrashHandler INSTANCE;
// Context
private Context mContext;
//
private Map infos = new HashMap();
private ZbCrashHandler(){
}
/**
*
*/
private static class SingletonHolder {
private static final ZbCrashHandler INSTANCE = new ZbCrashHandler();
}
public static ZbCrashHandler getINSTANCE(){
return SingletonHolder.INSTANCE;
}
/**
*
*/
public void init(Context context){
mContext = context;
// UncaughtException
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
// CrashHandler
Thread.setDefaultUncaughtExceptionHandler(this);
}
/**
* UncaughtException
*/
@Override
public void uncaughtException(Thread t, Throwable e) {
if (!handleException(e) && mDefaultHandler != null) {
//
mDefaultHandler.uncaughtException(t, e);
} else {
try {
Thread.sleep(3000);
} catch (InterruptedException ie) {
LogUtils.e(ie.toString());
}
//
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}
}
/**
* , .
*
* @param ex
* @return true: ; false.
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return false;
}
//
collectDeviceInfo(mContext);
//
saveCrashInfo2File(ex);
return true;
}
/**
*
*
* @param ctx
*/
private void collectDeviceInfo(Context ctx) {
try {
PackageManager pm = ctx.getPackageManager();
PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null) {
String versionName = pi.versionName == null ? "null" : pi.versionName;
String versionCode = pi.versionCode + "";
infos.put("versionName", versionName);
infos.put("versionCode", versionCode);
}
} catch (PackageManager.NameNotFoundException e) {
LogUtils.e(TAG,"CrashHandleran.NameNotFoundException---> error occured when collect package info");
}
//
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
infos.put(field.getName(), field.get(null).toString());
} catch (Exception e) {
LogUtils.e(TAG,"CrashHandler.NameNotFoundException---> an error occured when collect crash info");
}
}
}
/**
*
*
* @param ex
* @return ,
*/
private String saveCrashInfo2File(Throwable ex) {
if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Log.e(TAG,"sdcard unmounted, skip saveCrashInfo2File");
}
// 6.0
File dir = new File(PATH);
if(!dir.exists()){
dir.mkdirs();
}
long current = System.currentTimeMillis();
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(current));
String file_name = PATH+FILE_NAME+time+FILE_NAME_SUFFIX;
File file = new File(file_name);
try{
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file)));
pw.println(time);
StringBuffer sb = new StringBuffer();
for (Map.Entry entry : infos.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
sb.append(key + "=" + value + "
");
}
pw.println(sb.toString());
pw.println();
ex.printStackTrace(pw);
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(pw);
cause = cause.getCause();
}
}catch (Exception e){
Log.e(TAG,"save crash info into file failed");
}
return file_name;
}
public void uploadExceptionToServer(){
// TODO upload Ecxeption Message to Your Web server;
}
}
5. CrashHandler , , Application 。
public class App extends BaseApplication {
@Override
public void onCreate() {
super.onCreate();
ZbCrashHandler zbCrashHandler = ZbCrashHandler.getINSTANCE();
zbCrashHandler.init(getApplicationContext());
}
}
CrashHandler , , ! !
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.