Android - 打开app就崩溃的一种解决方案 - 拦截崩溃日志存在本地或者上传到服务器

1. 新建CrashHandler类,用来拦截crash事件,及时写入本地设备或者上传到服务器

public class CrashHandler implements Thread.UncaughtExceptionHandler {

    private static final String TAG = "CrashHandler";

    private static final String FILE_NAME = "crash";
    private static final String FILE_NAME_SUFFIX = ".log";

    private String fileName;
    private String serverUrl;

    private static CrashHandler sInstance = new CrashHandler();
    private Thread.UncaughtExceptionHandler mDefaultCrashHandler;
    private Context mContext;
    private FirebaseAnalytics mFirebaseAnalytics;

    private CrashHandler() {
    }

    public static CrashHandler getInstance() {
        return sInstance;
    }

    public void init(Context context) {
        mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
        mContext = context.getApplicationContext();
    }


    @RequiresApi(Build.VERSION_CODES.KITKAT)
    @Override
    public void uncaughtException(Thread t, Throwable ex) {
        try {
            String fileName = "stLog.log";
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
            StringWriter stringWriter = new StringWriter();
            PrintWriter printWriter = new PrintWriter(stringWriter);
            ex.printStackTrace(printWriter);
            printWriter.close();
            String unCaughtException = stringWriter.toString();// crash log details
            BreezeLog.d(TAG, "crash-test:"+unCaughtException);
            boolean isAvailable = sdCardIsAvailable(); // check your directory
            Log.d(TAG, "isAvailable "+isAvailable);
            dumpExceptionToSdCard(ex); //write crash log to local device 
        } catch (Exception e) {
            BreezeLog.d(TAG, "error in CrashHandler-uncaughtException");
        }
    }
@RequiresApi(Build.VERSION_CODES.KITKAT)
    private void dumpExceptionToSdCard(Throwable ex) {
        StringBuffer sb = new StringBuffer();
        Writer writer = new StringWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        dumpPhoneInfo(printWriter);
        ex.printStackTrace(printWriter);
        Throwable cause = ex.getCause();
        while (cause != null) {
            cause.printStackTrace(printWriter);
            cause = cause.getCause();
        }
        printWriter.close();
        String result = writer.toString();
        sb.append(result);
        try {
            long timestamp = System.currentTimeMillis();
            String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(timestamp));
            String filePath = "crash-test/";
            fileName = "crash-" + timestamp + ".txt";
            File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), filePath+fileName);
            if (!file.exists()) {
       // file.mkdirs(); 
             file.getParentFile().mkdirs(); 
      } 
      String content = sb.toString()+ "\r\n";
      RandomAccessFile raf = new RandomAccessFile(file, "rwd");
      raf.seek(file.length()); 
      raf.write(content.getBytes()); 
      raf.close(); 
    } catch (Exception e) { 
      Log.e(TAG, "an error occured while writing file...", e); 
    }
   }

   private void dumpPhoneInfo(PrintWriter pw) { 
    pw.print("Model: "); 
    pw.print(Build.MODEL); 
    pw.print("APU ABI: "); 
    pw.println(Build.CPU_ABI);
    //...
  }
    private void uploadExceptionToServer(String serverUrl, String file) {
        String end = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";
        try {
            URL url = new URL(serverUrl);
            HttpURLConnection con = (HttpURLConnection)url.openConnection();
            con.setDoInput(true);
            con.setDoOutput(true);
            con.setUseCaches(false);
            con.setRequestMethod("POST");
            con.setRequestProperty("Connection", "Keep-Alive");
            con.setRequestProperty("Charset", "UTF-8");
            con.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);

            String fileName = file.substring(file.lastIndexOf("/") + 1);
            DataOutputStream ds = new DataOutputStream(con.getOutputStream());
            ds.writeBytes(twoHyphens + boundary + end);
            ds.writeBytes("Content-Disposition: form-data;" + "name=\"file1\";filename=\"" + fileName + "\"" + end);
            ds.writeBytes(end);
            FileInputStream fStream = new FileInputStream(file);
            byte[] buffer = new byte[1024];
            int length = -1;
            while ((length =  fStream.read(buffer)) != -1) {
                ds.write(buffer, 0, length);
            }
            ds.writeBytes(end);
            ds.writeBytes(twoHyphens + boundary + twoHyphens + end);

            fStream.close();
            ds.flush();

            InputStream is = con.getInputStream();
            int ch;
            StringBuffer b = new StringBuffer();
            while ((ch =  is.read()) != -1) {
                b.append((char)ch);
            }

            ds.close();
            is.close();


        } catch (Exception e) {
            Log.d(TAG, "error in CrashHandler-uploadExceptionToServer");
        }

    }

    public static boolean sdCardIsAvailable() {
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            File sd = new File(Environment.getExternalStorageDirectory().getPath());
            Log.d("qq", "sd = " + sd);//sd = /storage/emulated/0
            return sd.canWrite();
        } else {
            return false;
        }
    }
}

2. 模拟crash事件

在你的MainActivity.java oncreate()方法里头加上这些,就可以模拟一打开app就crash了

CrashHandler crashHandler = CrashHandler.getInstance();
crashHandler.init(getApplicationContext());
int[] intarr = null;
BreezeLog.d(TAG, "error in "+ intarr[1]); // must have this line as it will get error

  

posted @ 2019-09-11 16:22  我是个神经病  阅读(1089)  评论(0)    收藏  举报