android 全局异常的处理 详解

Android游戏《歪把子炮》源码
http://www.eoeandroid.com/thread-197425-1-1.html

Android 新版捕鱼达人源码
http://www.eoeandroid.com/thread-197437-1-1.html

Android版本的手机RSS阅读器的源码
http://www.eoeandroid.com/thread-197465-1-1.html

 

最近新产品测试,频频出现异常。所以需要对异常进行全局捕捉。
翻阅大量帖子、源码终于找到了UncaughtExceptionHandler接口。废话不多说还是直接上源码吧。


首先实现UncaughtExceptionHandler

复制代码
public class CatchHandler implements UncaughtExceptionHandler{
 
        private CatchHandler() {
        }
 
        public static CatchHandler getInstance() {
 
                return mCatchHandler;
        }
 
        private static CatchHandler mCatchHandler = new CatchHandler();
 
        private Context mContext;
 
        private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
 
        @Override
        public void uncaughtException(Thread thread, Throwable ex) {
                if (thread.getName().equals("main")) {
                        ToastException(thread, ex);
                        try {
                                Thread.sleep(3000);
                        } catch (InterruptedException e) {
                        }
                        android.os.Process.killProcess(android.os.Process.myPid());
                        System.exit(1);
                } else {
                        handleException(thread, ex);
                }
 
        }
 
        public void init(Context context) {
                mContext = context;
                Thread.setDefaultUncaughtExceptionHandler(this);
        }
 
        private void ToastException(final Thread thread, final Throwable ex) {
                new Thread() {
                        @Override
                        public void run() {
                                Looper.prepare();
                                StringBuilder builder = new StringBuilder();
                                builder.append("At thread: ").append(thread.getName())
                                                .append("\n");
                                builder.append("Exception is :\n").append(ex.getMessage());
 
                                Toast.makeText(mContext, builder.toString(), Toast.LENGTH_LONG)
                                                .show();
                                Looper.loop();
                        }
                }.start();
        }
 
        private void handleException(final Thread thread, final Throwable ex) {
                Intent intent =new Intent("per.xch.test2_35.main");
                <font color="#00ed00">intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);</font>
                mContext.startActivity(intent);
        }
}
复制代码

然后在项目中引用

public class CatchApplication extends Application {
        @Override
        public void onCreate() {
                super.onCreate();
                CatchHandler.getInstance().init(getApplicationContext());
        }
}

注意

<application
        <font color="#00ed00">android:name=".CatchApplication"</font>

最后测试下

复制代码
public class MainActivity extends Activity {
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         
        new Thread(new Runnable() {
                         
                        @Override
                        public void run() {
                                 throw new NullPointerException("please catch me! sub thread");
                        }
                }).start();
        throw new NullPointerException("please catch me! sub thread");
        
    }
 
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}
复制代码

之所以在主线程和其他线程采用不同处理方式因为主线程崩溃很大程度上就没的救了。
还有要注意的是intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
原因很简单,源码写的很明白


ContextImpl.java

复制代码
  @Override
    public void startActivity(Intent intent) {
        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
            throw new AndroidRuntimeException(
                    "Calling startActivity() from outside of an Activity "
                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
                    + " Is this really what you want?");
        }
        mMainThread.getInstrumentation().execStartActivity(
            getOuterContext(), mMainThread.getApplicationThread(), null,
            (Activity)null, intent, -1);
    }
复制代码

至于怎么把activity怎么变成dialog我就不废话喽,吼,闪人。

 

原文链接:http://www.eoeandroid.com/thread-197442-1-1.html

 

 

posted on   vus520  阅读(3494)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架

导航

< 2012年9月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 1 2 3 4 5 6
点击右上角即可分享
微信分享提示