android 快速开发三、 获取应用的crash信息
来源:互联网 发布:进口儿童安全座椅知乎 编辑:程序博客网 时间:2024/05/29 19:56
当用户发生了crash,开发者却无法得知程序为何crash,即便开发人员想去解决这个crash,但是由于无法知道用户当时crash信息,所以往往无能为力。android 提供了获取crash信息的方法。话不多说,直接上代码。
package com.example.wmk.utils;import android.content.Context;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.os.Build;import com.lidroid.xutils.util.LogUtils;import java.io.BufferedWriter;import java.io.File;import java.io.FileWriter;import java.io.PrintWriter;/** * Created by 老王 on 2016/12/2. */public class CrashHandler implements Thread.UncaughtExceptionHandler { /** * CrashHandler */ private static CrashHandler CRASHHANDLER = null; private Thread.UncaughtExceptionHandler mDefaultUncaughtExceptionHandler; private Context mContext; private static final String FILE_NAME = "crash"; private static final String FILE_NAME_TXT = ".txt"; /** * Get Instance * * @return CrashHandler */ public static CrashHandler getInstance() { if (CRASHHANDLER == null) { CRASHHANDLER = new CrashHandler(); } return CRASHHANDLER; } private CrashHandler() { } public void init(Context context) { mDefaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); mContext = context.getApplicationContext(); } @Override public void uncaughtException(Thread thread, Throwable ex) { //导出异常信息到SD卡中 dumpExceptionToSDCard(ex); //这里可以上传异常信息到服务器,便于开发人员分析日志从而解决bug uploadExceptionToServer(); ex.printStackTrace(); //如果系统提供了默认的异常处理器,则交给系统去结束程序,否则就由自己结束自己 if (mDefaultUncaughtExceptionHandler != null) { mDefaultUncaughtExceptionHandler.uncaughtException(thread, ex); } else { ActivityManager.getInstance().appExceptionExit(); } } private void dumpExceptionToSDCard(Throwable ex) { String time = TimeUtils.formatDate("yyyy-MM-dd HH:mm:ss"); //创建crash文件 File file = ProjectUtils.createFile(ProjectUtils.WMK_LOG + FILE_NAME + time + FILE_NAME_TXT); try { PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(file))); pw.println(time); dumpPhoneInfo(pw); pw.println(); ex.printStackTrace(pw); pw.close(); } catch (Exception e) { LogUtils.e("dump crash info failed"); } } private void dumpPhoneInfo(PrintWriter pw) throws PackageManager.NameNotFoundException { PackageManager pm = mContext.getPackageManager(); PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES); pw.print("App Version: "); pw.print(pi.versionName); pw.print("_"); pw.println(pi.versionCode); //Android版本号 pw.print("OS Version: "); pw.print(Build.VERSION.RELEASE); pw.print("_"); pw.println(Build.VERSION.SDK_INT); //手机制造商 pw.print("Vendor: "); pw.println(Build.MANUFACTURER); //手机型号 pw.print("Model: "); pw.println(Build.MODEL); //CPU架构 pw.print("CPU ABI:"); pw.println(Build.CPU_ABI); } private void uploadExceptionToServer() { //TODO Upload Exception Message To your Web Server }}
首先,封装了一个日期工具类,用于显示日期,代码如下:
package com.example.wmk.utils;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Locale;/** * Created by 老王 on 2016/12/2. */public class TimeUtils { /** * 格式化当前日期 * * @param rule 格式规则 * @return 格式化后的日期 */ public static String formatDate(String rule) { return new SimpleDateFormat(rule, Locale.getDefault()).format(new Date()); }}
其次,用到了项目工具类中的创建文件的方法。
package com.example.wmk.utils;import android.os.Environment;import java.io.File;/** * Created by 老王 on 2016/12/1. */public class ProjectUtils { /** * 根目录 */ public static File ROOT_DIRECTORY = Environment.getExternalStorageDirectory(); /** * 项目路径 */ public static final String PROJECT_PATH = ROOT_DIRECTORY.getAbsolutePath() + "/WMK/"; /** * 数据库 */ public static final String WMK_DB = PROJECT_PATH + "DB/"; /** * 图片 */ public static final String WMK_IMG = PROJECT_PATH + "IMG/"; /** * Log */ public static final String WMK_LOG = PROJECT_PATH + "LOG/"; /** * sdCard * * @return If there is a SD card to return true, otherwise false */ public static boolean existsSdCard() { return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); } /** * 创建文件 * * @param s * @return If you create a file successfully returned to the current file, otherwise * Null */ public static File createFile(String s) { return new File(s); } /** * 创建文件夹 * * @param s * @return If you create a folder successfully returned to the current folder, otherwise * Null */ public static File createFolder(String s) { File file = new File(s); if (!file.exists()) { file.mkdirs(); } return file; } /** * 初始化 * * @return If true is returned to the initial success, otherwise false */ public static boolean init() { boolean result = false; if (existsSdCard()) { result = true; result &= createFolder(PROJECT_PATH) != null; result &= createFolder(WMK_DB) != null; result &= createFolder(WMK_IMG) != null; result &= createFolder(WMK_LOG) != null; } return result; }}
最后,在application中,捕获crash信息,代码如下:
package com.example.wmk;import android.app.Activity;import android.app.Application;import android.os.Build;import android.os.Bundle;import com.example.wmk.utils.ActivityManager;import com.example.wmk.utils.CrashHandler;import com.example.wmk.utils.ProjectUtils;import com.lidroid.xutils.util.LogUtils;/** * Created by 老王 on 2016/12/1. */public class WMKApplication extends Application { ActivityManager mActivityManager; @Override public void onCreate() { super.onCreate(); //init ActivityManager mActivityManager = ActivityManager.getInstance(); // 注册activity监听器 registerActivityListener(); if (ProjectUtils.init()) { //在这里为应用设置异常处理,然后程序才能获取未处理的异常 CrashHandler crashHandler = CrashHandler.getInstance(); crashHandler.init(this); } else { mActivityManager.appExceptionExit(); } } private void registerActivityListener() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { /** * 监听到 Activity创建事件 将该 Activity 加入list */ mActivityManager.pushActivity(activity); /** * 栈顶元素名称 */ LogUtils.d("TopActivityName:" + mActivityManager.getTopActivityName()); } @Override public void onActivityStarted(Activity activity) { } @Override public void onActivityResumed(Activity activity) { } @Override public void onActivityPaused(Activity activity) { } @Override public void onActivityStopped(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityDestroyed(Activity activity) { if (null == mActivityManager.getActivitys() && mActivityManager.getActivitys().isEmpty()) { return; } if (mActivityManager.getActivitys().contains(activity)) { /** * 监听到 Activity销毁事件 将该Activity 从list中移除 */ mActivityManager.popActivity(activity); } } }); } }}
下面在activity中抛出一个异常,布局文件如下:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".activity.MainActivity"> <Button android:id="@+id/btn_crash" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="crash" /></RelativeLayout>
activity界面代码如下:
package com.example.wmk.activity;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.Button;import com.example.wmk.R;import com.lidroid.xutils.ViewUtils;import com.lidroid.xutils.view.annotation.ViewInject;public class MainActivity extends Activity { @ViewInject(R.id.btn_crash) private Button btnCrash = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewUtils.inject(this); initOnclickListener(); } private void initOnclickListener() { View.OnClickListener onClickListener = new View.OnClickListener() { @Override public void onClick(View v) { if (v == btnCrash) { throw new RuntimeException("自定义异常"); } } }; btnCrash.setOnClickListener(onClickListener); }}
点击自定义异常按钮,抛出crash信息,在SDCard中,会产生一个crash文件,如图:
最后可以把用户的crash信息上传服务器。
1 0
- android 快速开发三、 获取应用的crash信息
- Android 获取应用Crash信息的方法
- Android中获取应用的crash信息
- Android 使用 CrashHandler 来获取应用的 crash 信息
- Android 使用CrashHandler获取应用的crash信息
- Android开发中获取crash信息
- 通过CrashHandler获取应用的crash信息
- 使用CrashHandler获取应用的crash信息
- Android如何捕获应用的crash信息
- 使用CrashHandler来获取应用的Crash信息
- 使用CrashHandler来获取应用的oom crash信息
- 实现UncaughtExceptionHandler来实现获取应用全局的crash信息
- 使用CrashHandler来获取应用的crash信息
- 使用CrashHandler来获取应用的crash信息
- 使用CrashHandler来获取(收集)应用的crash信息
- Android应用Crash信息收集
- Android系统获取应用的Crash信息,保存在本地(可以自己实现上传到自己的服务器)
- Android和IOS获取crash信息
- Retrofit2.0
- 利用Android Studio、MAT对Android进行内存泄漏检测
- php 将数组结果作为返回值保存到php文件中
- WinCE下,快速编译驱动及BSP
- 嵌入式系统知识体系、学习误区及建议
- android 快速开发三、 获取应用的crash信息
- 掌握感性思路,轻松写出高质量的SEO原创文章
- 关于object类的初次认识
- spring 基于注解的@Scheduled和quartz定时器两种实现
- python第三方库安装和卸载注意事项
- Python--Python抓取花椒网人气主播全教程(附:代码)
- >> << 0xf 等用法
- sql server 2008 远程订阅发布
- Android自定义标题栏:显示网页加载进度