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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架