google目前也有个项目在处理这个问题http://code.google.com/p/acra/,不过那个包有点大,好几十k呢,如果我们想自我定制下,最重要的知识点就是
1.拦截UncaughtException
Application.onCreate()是整个Android应用的入口方法。在该方法中执行如下代码即可拦截UncaughtException:
ueHandler = new UEHandler(this); // 设置异常处理实例 Thread.setDefaultUncaughtExceptionHandler(ueHandler);2.抓取导致程序崩溃的异常信息
UEHandler是Thread.UncaughtExceptionHandler的实现类,在其public void uncaughtException(Thread thread, Throwable ex)的实现中可以获取崩溃信息,代码如下:
package lab.sodino.uncaughtexception; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; import android.content.Intent; import android.util.Log; /** * @author Sodino E-mail:[email protected] * @version Time:2011-6-9 下午11:50:43 */ public class UEHandler implements Thread.UncaughtExceptionHandler { private SoftApplication softApp; private File fileErrorLog; public UEHandler(SoftApplication app) { softApp = app; fileErrorLog = new File(SoftApplication.PATH_ERROR_LOG); } @Override public void uncaughtException(Thread thread, Throwable ex) { // fetch Excpetion Info 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(); } } // print long threadId = thread.getId(); Log.d("ANDROID_LAB", "Thread.getName()=" + thread.getName() + " id=" + threadId + " state=" + thread.getState()); Log.d("ANDROID_LAB", "Error[" + info + "]"); if (threadId != 1) { // 此处示例跳转到汇报异常界面。 Intent intent = new Intent(softApp, ActErrorReport.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra("error", info); intent.putExtra("by", "uehandler"); softApp.startActivity(intent); } else { // 此处示例发生异常后,重新启动应用 Intent intent = new Intent(softApp, ActOccurError.class); // 如果<span style="background-color: rgb(255, 255, 255); ">没有NEW_TASK标识且</span>是UI线程抛的异常则界面卡死直到ANR intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); softApp.startActivity(intent); // write 2 /data/data/<app_package>/files/error.log write2ErrorLog(fileErrorLog, info); // kill App Progress android.os.Process.killProcess(android.os.Process.myPid()); } } private void write2ErrorLog(File file, String content) { FileOutputStream fos = null; try { if (file.exists()) { // 清空之前的记录 file.delete(); } else { file.getParentFile().mkdirs(); } file.createNewFile(); fos = new FileOutputStream(file); fos.write(content.getBytes()); } catch (Exception e) { e.printStackTrace(); } finally { try { if (fos != null) { fos.close(); } } catch (Exception e) { e.printStackTrace(); } } } }
this.getBaseContext().getMainLooper().getThread().getId()上面取到的值确实是个1,即使在application的oncreate中先启动个thread,这个再研究下ActivityThread了
其他的内容参见http://blog.csdn.net/sodino/archive/2011/06/13/6540329.aspx
本文内容归CSDN博客博主Sodino 所有
转载请注明出处: http://blog.csdn.net/sodino/archive/2011/06/13/6540329.aspx