CrashHandler를 사용하여 어플리케이션에 대한 crash 정보를 얻습니다.

8081 단어 Android
1. 안드로이드 응용 프로그램에서crash가 발생하는 것을 피할 수 없다. 붕괴라고도 부른다. 프로그램이 아무리 완벽하게 쓰여져도crash의 발생을 완전히 피할 수 없다. 안드로이드 시스템의 밑에 있는 버그 때문일 수도 있고 충분하지 않은 기종이 어울리거나 네트워크 상황 때문일 수도 있다.crash가 발생할 때, 시스템은 실행 중인 프로그램을 삭제합니다. 이것은 사용자가 실행을 중지했음을 알리거나 깜빡깜빡하는 것입니다.이것은 사용자에게 매우 불친절한 것이고 개발자가 보고 싶지 않은 것이다. 더 심각한 것은 사용자가crash가 발생하면 개발자는 프로그램이 왜crash인지 알 수 없다.
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 , , ! !




좋은 웹페이지 즐겨찾기