- 浏览: 214507 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (196)
- android (153)
- sqlite (1)
- java (3)
- os (4)
- tools (4)
- ResolveInfo 转 packageinf 取信息 (1)
- multimedia (2)
- fastboot (1)
- create user in samba (0)
- android qcn (0)
- windows (0)
- net (2)
- linux (1)
- git (0)
- proguard (0)
- android cpu (1)
- android gts (1)
- MySql (1)
- c/c++ (0)
- network (1)
- python (3)
- AI (1)
- Ultroedit (1)
- HarmonyOS NEXT (0)
From: https://blog.csdn.net/dreamintheworld/article/details/43669027
网上关于安卓开发过程中出现的异常捕抓问题已经讲得非常透彻了,现在为自己总结一下使用UncaughtExceptionHandler捕抓程序中没有处理的异常,不至于弹出:
那么这里的程序结构为:
代码如下:
这样就能在
mnt/sdcard/crash目录下看到异常信息:
信息内容为:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.exceptionlog/com.example.exceptionlog.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.example.exceptionlog.MainActivity.onCreate(MainActivity.java:16)
at android.app.Activity.performCreate(Activity.java:5104)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
... 11 more
java.lang.NullPointerException
at com.example.exceptionlog.MainActivity.onCreate(MainActivity.java:16)
at android.app.Activity.performCreate(Activity.java:5104)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
这里不要忘记写入权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
项目中正常使用的实际案例,并且保存设备信息:
网上关于安卓开发过程中出现的异常捕抓问题已经讲得非常透彻了,现在为自己总结一下使用UncaughtExceptionHandler捕抓程序中没有处理的异常,不至于弹出:
那么这里的程序结构为:
代码如下:
public class CrashHandler implements UncaughtExceptionHandler { public static final String TAG = "CrashHandler"; // 系统默认的UncaughtException处理类 private Thread.UncaughtExceptionHandler mDefaultHandler; // CrashHandler实例 private static CrashHandler INSTANCE = new CrashHandler(); // 程序的Context对象 private Context mContext; // 用来存储设备信息和异常信息 private Map<String, String> infos = new HashMap<String, String>(); // 用于格式化日期,作为日志文件名的一部分 @SuppressLint("SimpleDateFormat") private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); /** 保证只有一个CrashHandler实例 */ private CrashHandler() { } /** 获取CrashHandler实例 ,单例模式 */ public static CrashHandler getInstance() { return INSTANCE; } /** * 初始化 * * @param context */ public void init(Context context) { mContext = context; // 获取系统默认的UncaughtException处理器 mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); // 设置该CrashHandler为程序的默认处理器 Thread.setDefaultUncaughtExceptionHandler(this); } /** * 当UncaughtException发生时会转入该函数来处理 */ @Override public void uncaughtException(Thread thread, Throwable ex) { Log.e("CrashHandler", "异常退出程序#0"); // if (!handleException(ex) && mDefaultHandler != null) { if (!handleException(ex) && mDefaultHandler != null) { // 如果用户没有处理则让系统默认的异常处理器来处理 mDefaultHandler.uncaughtException(thread, ex); } else { try { Thread.sleep(3000); } catch (InterruptedException e) { Log.e(TAG, "error : ", e); } for(Activity activity : CrashApplication.mylist){ activity.finish(); } CrashApplication.mylist.clear(); Toast.makeText(mContext, "上传完成", Toast.LENGTH_SHORT).show(); android.os.Process.killProcess(android.os.Process.myPid()); System.exit(0); Looper.myLooper().quit(); } } /** * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. * * @param ex * @return true:如果处理了该异常信息;否则返回false. */ private boolean handleException(Throwable ex) { if (ex == null) { return false; } // 使用Toast来显示异常信息 new Thread() { @Override public void run() { Looper.prepare(); Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_LONG) .show(); Looper.loop(); } }.start(); // 收集设备参数信息 collectDeviceInfo(mContext); // 保存日志文件 saveCrashInfo2File(ex); return true; } /** * 收集设备参数信息 * * @param ctx */ public void collectDeviceInfo(Context ctx) { try { PackageManager pm = ctx.getPackageManager(); PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES); if (pi != null) { String versionName = pi.versionName == null ? "null" : pi.versionName; String versionCode = pi.versionCode + ""; infos.put("versionName", versionName); infos.put("versionCode", versionCode); } } catch (NameNotFoundException e) { Log.e(TAG, "an error occured when collect package info", e); } Field[] fields = Build.class.getDeclaredFields(); for (Field field : fields) { try { field.setAccessible(true); infos.put(field.getName(), field.get(null).toString()); Log.d(TAG, field.getName() + " : " + field.get(null)); } catch (Exception e) { Log.e(TAG, "an error occured when collect crash info", e); } } } /** * 保存错误信息到文件中 * * @param ex * @return 返回文件名称,便于将文件传送到服务器 */ private String saveCrashInfo2File(Throwable ex) { StringBuffer sb = new StringBuffer(); for (Map.Entry<String, String> entry : infos.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); sb.append(key + "=" + value + "\n"); } Writer writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); 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 = formatter.format(new Date()); String fileName = "crash-" + time + "-" + timestamp + ".log"; if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/crash/"; File dir = new File(path); if (!dir.exists()) { dir.mkdirs(); } FileOutputStream fos = new FileOutputStream(path + fileName); fos.write(sb.toString().getBytes()); fos.close(); } return fileName; } catch (Exception e) { Log.e(TAG, "an error occured while writing file...", e); } return null; } } CrashApplication.java [java] view plain copy public class CrashApplication extends Application { public static List<Activity> mylist = new ArrayList<Activity>(); @Override public void onCreate() { super.onCreate(); CrashHandler crashHandler = CrashHandler.getInstance(); crashHandler.init(getApplicationContext()); } } 在MainActivity.java 中制造异常: [java] view plain copy public class MainActivity extends Activity { String s; @Override protected void onCreate(Bundle savedInstanceState) { CrashApplication.mylist.add(this); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); System.out.println(s.equals("any string")); } }
这样就能在
mnt/sdcard/crash目录下看到异常信息:
信息内容为:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.exceptionlog/com.example.exceptionlog.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.example.exceptionlog.MainActivity.onCreate(MainActivity.java:16)
at android.app.Activity.performCreate(Activity.java:5104)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
... 11 more
java.lang.NullPointerException
at com.example.exceptionlog.MainActivity.onCreate(MainActivity.java:16)
at android.app.Activity.performCreate(Activity.java:5104)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
这里不要忘记写入权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
项目中正常使用的实际案例,并且保存设备信息:
import java.io.File; import java.io.FileOutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.Thread.UncaughtExceptionHandler; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.TimeZone; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Build; import android.os.Environment; /** * @author Admin * @Funtion 异常处理 */ public class CrashHandler implements UncaughtExceptionHandler { private Thread.UncaughtExceptionHandler mDefaultHandler; private static CrashHandler instance ; private Context context; public static CrashHandler getInstance() { if(instance == null){ instance = new CrashHandler(); } return instance; } @Override public void uncaughtException(Thread thread, Throwable ex) { savaInfoToSD(context, ex); if (ex == null && mDefaultHandler != null) { mDefaultHandler.uncaughtException(thread, ex); } else { Intent intent = new Intent(context, ExceptionActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); android.os.Process.killProcess(android.os.Process.myPid()); System.exit(1); } } public void init(Context context) { this.context = context; if(mDefaultHandler == null){ // mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); // Thread.setDefaultUncaughtExceptionHandler(this); } } /** * 保存获取的 软件信息,设备信息和出错信息保存在SDcard中 * * @param context * @param ex * @return */ private String savaInfoToSD(Context context, Throwable ex) { String fileName = null; StringBuffer sb = new StringBuffer(); for (Map.Entry<String, String> entry : obtainSimpleInfo(context) .entrySet()) { String key = entry.getKey(); String value = entry.getValue(); sb.append(key).append(" = ").append(value).append("\n"); } sb.append(obtainExceptionInfo(ex)); if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { String dirPath = Environment.getExternalStorageDirectory() .getPath().toString() + "/"; File dir = new File(dirPath + "crashForDeveloper" + File.separator); if (!dir.exists()) { dir.mkdir(); } File[] files = dir.listFiles(); if(files.length > 20){ // delete when record over 20 for(int i=0;i<files.length;i++){ files[i].delete(); } } try { fileName = dir.toString() + File.separator + paserTime(System.currentTimeMillis()) + ".log"; FileOutputStream fos = new FileOutputStream(fileName); fos.write(sb.toString().getBytes()); fos.flush(); fos.close(); } catch (Exception e) { e.printStackTrace(); } } return fileName; } /** * 获取一些简单的信息,软件版本,手机版本,型号等信息存放在HashMap中 * * @param context * @return */ private HashMap<String, String> obtainSimpleInfo(Context context) { HashMap<String, String> map = new HashMap<String, String>(); PackageManager mPackageManager = context.getPackageManager(); PackageInfo mPackageInfo = null; try { mPackageInfo = mPackageManager.getPackageInfo( context.getPackageName(), PackageManager.GET_ACTIVITIES); } catch (NameNotFoundException e) { e.printStackTrace(); } map.put("versionName", mPackageInfo.versionName); map.put("versionCode", "" + mPackageInfo.versionCode); map.put("MODEL", "" + Build.MODEL); map.put("SDK_INT", "" + Build.VERSION.SDK_INT); map.put("PRODUCT", "" + Build.PRODUCT); return map; } /** * 将毫秒数转换成yyyy-MM-dd-HH-mm-ss的格式 * * @param milliseconds * @return */ private String paserTime(long milliseconds) { System.setProperty("user.timezone", "Asia/Shanghai"); TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai"); TimeZone.setDefault(tz); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); String times = format.format(new Date(milliseconds)); return times; } /** * 获取系统未捕捉的错误信息 * * @param throwable * @return */ private String obtainExceptionInfo(Throwable throwable) { StringWriter mStringWriter = new StringWriter(); PrintWriter mPrintWriter = new PrintWriter(mStringWriter); throwable.printStackTrace(mPrintWriter); mPrintWriter.close(); // Log.e(TAG, mStringWriter.toString()); return mStringWriter.toString(); } }
发表评论
-
Android SnappyDB
2018-05-15 11:23 953https://blog.csdn.net/qq_214305 ... -
android udp
2018-04-10 19:47 594Android之Socket的基于UDP传输 接收方创建步骤: ... -
android DownloadManager
2018-04-10 12:52 587From: https://www.jianshu.com/p ... -
Snackbar 可以交互的Toast
2018-04-08 21:44 758Snackbar 是 Android design sup ... -
android 操作串口
2018-03-19 18:20 651http://blog.csdn.net/akunainian ... -
proguard对 android-support-v4.jar 的配置
2018-03-16 15:32 717-libraryjars libs/android-sup ... -
apk 多个dex
2018-03-16 10:05 998android studio 配置应用生成多个dex ... -
ddmlib 解决android n file explorer 为空问题
2018-03-16 09:27 930百度云:http://pan.baidu.com/s/1sl4 ... -
android 代码混淆
2018-03-15 08:38 1044打开混淆开关 Android.mk ... -
menu item 显示icon
2018-03-07 09:32 677@Override public boolean onMenu ... -
ubuntu 脚本切换root用户,并执行其它脚本
2018-03-05 09:58 0#!/bin/bash expect -c" ... -
DrawerLayout 滑动侧边栏
2018-03-01 10:42 0// TODO -
jack-server 多用户编译问题
2018-02-27 10:44 14013),需要同时修改 $HOME/.jack-server/co ... -
更新eclipse 遇到两个问题 Oxygen.2 Release (4.7.2)
2018-02-26 14:28 12261. the file dx.jar was not load ... -
监听系统开关变化
2018-02-05 14:02 812// 转屏开关 /** * Content obse ... -
android 8.0 模块编译命令
2018-02-02 14:42 1170Invoke ". build/envsetup.s ... -
svn checkout 忽略某个文件夹
2018-01-26 11:14 1361android源码更新时, frameworks\compil ... -
eclipse jni
2018-01-19 16:10 493试过,可以运行 http://blog.csdn.net/sb ... -
opencv for android
2018-01-19 14:37 434http://blog.csdn.net/sbsujjbcy/ ... -
Cordova // TODO
2018-01-18 11:12 340Cordova提供了一组设备相关的API,通过这组API,移动 ...
相关推荐
为了解决这个问题,开发者可以使用`UncaughtExceptionHandler`来捕获全局异常,从而进行自定义的错误处理和日志记录,甚至有可能恢复应用的正常运行。以下是对这一技术的详细解释。 `UncaughtExceptionHandler`是...
Android捕获全局异常并写日志保存到sd卡,捕获异常消息后输出这个消息,可避免APP强制退出,抛出NullPointException玩玩哈,捕获全局异常是因为有的异常我们捕获不到,捕获时我们采用同步方法,以免单例多线程环境下...
在Android中,我们可以通过创建一个自定义的`Thread.UncaughtExceptionHandler`并将其设置为应用的默认异常处理器来实现全局异常捕获。`Thread.UncaughtExceptionHandler`是Java线程处理未捕获异常的接口,当线程抛...
总的来说,全局异常捕获是通过自定义`UncaughtExceptionHandler`并设置为系统默认处理器来实现的,这使得开发者可以在一个集中的位置处理所有未被捕获的异常,提供了更健壮的错误处理策略。在实际项目中,我们还应该...
全局异常捕获是指在整个应用程序运行过程中,无论在哪个线程、哪个模块抛出未被捕获的异常时,都能进行有效的处理,避免应用突然崩溃。这通常通过实现自定义的异常处理器来实现。本主题将深入探讨Android全局异常...
为了解决这个问题,开发者通常会采用全局异常捕获机制,即创建一个自定义的`CrashHandler`,来捕获并处理这些未被捕获的异常。本篇文章将深入探讨Android全局异常捕获`CrashHandler`的相关知识点,以及如何实现和...
总结,Android全局异常处理是通过创建自定义的`Thread.UncaughtExceptionHandler`并设置为全局处理器来实现的,这样可以统一处理所有未捕获异常,保证应用的稳定性。同时,通过存储异常信息到本地和上传到服务器,...
本篇主要介绍如何实现一个全局的异常处理机制,以便将未处理的异常日志保存到本地文件,并在后续开发中将这些日志提交至服务器进行分析。 首先,我们需要创建一个`ExceptionHandler`类,这个类将会作为全局的错误...
在Android中,我们可以通过自定义`Thread.UncaughtExceptionHandler`来实现全局异常捕获。创建一个类,继承这个接口,并重写`uncaughtException`方法,里面可以添加将异常信息记录到日志或发送报告的代码。 2. **...
为了实现全局异常捕获,我们需要创建一个类去继承`Thread.UncaughtExceptionHandler`,并重写`uncaughtException`方法。通常,我们还会在这个方法中添加日志记录或者发送错误报告的逻辑,以便开发者能够远程追踪到...
本文将详细讲解如何在Android中实现全局异常捕获,特别是如何将运行时异常写入到SD卡中。 首先,我们需要创建一个全局异常处理器。在Android应用中,我们可以利用`Application`类来实现这一功能。`Application`类是...
我们可以通过重写`UncaughtExceptionHandler`并将其设置为应用程序的默认处理器来捕获全局异常。 以下是实现步骤: 1. **创建自定义CrashHandler类**:首先,我们需要创建一个继承自`Thread....
本文将详细讲解如何在Android中实现全局异常捕获,包括在崩溃前显示提示信息、保存错误日志到本地、发送错误报告邮件以及将错误信息上传至后台服务器。 一、创建全局异常监听器 首先,我们需要创建一个能监听整个...
总结起来,Android全局异常捕获通过自定义`Thread.UncaughtExceptionHandler`并设置为系统默认异常处理器,可以在应用中全局捕获并处理未被捕获的异常。这不仅可以帮助开发者追踪和修复错误,还能提供更好的用户体验...
- **全局异常处理**:设置`UncaughtExceptionHandler`来捕获未被其他catch块处理的异常。 - **避免ANR**:确保主线程不执行耗时操作,使用AsyncTask或其他异步方法处理后台任务。 - **日志记录**:使用Android的...
1. **全局异常捕获**: 在Android应用中,全局异常捕获通常通过自定义的`UncaughtExceptionHandler`实现。这个处理器会捕获那些没有被应用程序内部捕获的运行时异常,防止应用因为未处理的异常而突然退出。 2. **...
全局异常处理器通常是在Application的onCreate()方法中设置的,通过注册一个Thread.UncaughtExceptionHandler。 下面是一段简单的全局异常捕获的源码示例: ```java public class MyApplication extends ...
在Android或iOS等移动平台,可以使用系统提供的异常处理接口,如Android的UncaughtExceptionHandler或者iOS的NSSetUncaughtExceptionHandler,来设置全局的未捕获异常处理器。在Java或C#等语言中,可以使用try-catch...
为了解决这个问题,开发者通常会实现全局异常捕获机制,以便在程序崩溃时记录异常信息,并将这些日志保存到本地。此外,为了维护存储空间的有效利用,日志还需要定时清理。本文将详细介绍如何在Android中实现这一...
通过以上步骤,开发者可以构建一个完善的全局异常处理机制,提升应用的稳定性和用户体验。在实际项目中,`MyCrashHandler`的实现细节会因需求而异,可能包括更多定制化的功能,例如集成崩溃报告服务、收集设备信息等...