android Activity崩潰日誌收集

Main-zy發表於2016-06-30

 每個android應用都是由一個Application和多個activity或者server構成.應用啟動時,會首先啟動Application.在Application的onCreate方法中呼叫

Thread.setDefaultUncaughtExceptionHandler(handler);

就可以捕獲導致應用崩潰的錯誤資訊了.

首先應用要有讀寫sd卡許可權

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

自定義一個Application,並在AndroidManifest.xml中使用這個Application

<application
        android:name=".MyApplication">
        ...
</application>

public class MyApplication extends Application {
    private static final String LOG_DIR = Environment
            .getExternalStorageDirectory().getAbsolutePath() + "/oldfeel/log/";
    private static final String LOG_NAME = getCurrentDateString() + ".txt";
    private ArrayList<Activity> list = new ArrayList<Activity>();

    @Override
    public void onCreate() {
        super.onCreate();
        Thread.setDefaultUncaughtExceptionHandler(handler);
    }

    UncaughtExceptionHandler handler = new UncaughtExceptionHandler() {

        @Override
        public void uncaughtException(Thread thread, Throwable ex) {
            writeErrorLog(ex);
            Intent intent = new Intent(getApplicationContext(),
                    CollapseActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
            exit();
        }
    };

    /**
     * 列印錯誤日誌
     * 
     * @param ex
     */
    protected void writeErrorLog(Throwable ex) {
        String info = null;
        ByteArrayOutputStream baos = null;
        PrintStream printStream = null;
        try {
            baos = new ByteArrayOutputStream();
            printStream = new PrintStream(baos);
            ex.printStackTrace(printStream);
            byte[] data = baos.toByteArray();
            info = new String(data);
            data = null;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (printStream != null) {
                    printStream.close();
                }
                if (baos != null) {
                    baos.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        Log.d("example", "崩潰資訊\n" + info);
        File dir = new File(LOG_DIR);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        File file = new File(dir, LOG_NAME);
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(file, true);
            fileOutputStream.write(info.getBytes());
            fileOutputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 獲取當前日期
     * 
     * @return
     */
    private static String getCurrentDateString() {
        String result = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd",
                Locale.getDefault());
        Date nowDate = new Date();
        result = sdf.format(nowDate);
        return result;
    }

    /**
     * Activity關閉時,刪除Activity列表中的Activity物件
     */
    public void removeActivity(Activity a) {
        list.remove(a);
    }

    /**
     * 向Activity列表中新增Activity物件
     */
    public void addActivity(Activity a) {
        list.add(a);
    }

    /**
     * 關閉Activity列表中的所有Activity
     */
    public void exit() {
        for (Activity activity : list) {
            if (null != activity) {
                activity.finish();
            }
        }
        // 殺死該應用程式
        android.os.Process.killProcess(android.os.Process.myPid());
    }
}

系統錯誤後要還是要提示使用者系統錯誤.這個是崩潰activity,

<activity
    android:name="com.example.test.CollapseActivity"
    android:theme="@android:style/Theme.Holo.Dialog.MinWidth" >
</activity>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="horizontal" >

    <Button
        android:id="@+id/collapse_restart"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1.0"
        android:text="重啟應用" />

    <Button
        android:id="@+id/collapse_exit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1.0"
        android:text="退出應用" />

</LinearLayout>

public class CollapseActivity extends Activity {
    private Button btnRestart, btnExit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.collapse_activity);
        setTitle("應用崩潰了");
        btnRestart = (Button) findViewById(R.id.collapse_restart);
        btnExit = (Button) findViewById(R.id.collapse_exit);
        btnRestart.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(),
                        MainActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
                finish();
            }
        });
        btnExit.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
}


相關文章