切换风格

默认Lavender Sky Flowers Wizard Snow Beige California City Dragon Black London Sunset glow Pink Cloud
12下一页

28

主题

278

积分

3

精华

用户组 

易积分
33123
热心
2
好评
29

热心会员

软件崩溃日志输出接口[复制链接]
发表于 2018-5-11 16:33:42 | 显示全部楼层 |阅读模式
很多时候,我们在写APP的时候,编译的时候不提示错误,但是软件运行的过程中却会出现奔溃或是停止运行的现象。
这个时候,你就需要输出你的APP崩溃的日志,然后通过查看日志来诊断APP到底是哪里出了问题

1.jpg

这样我们修复APP崩溃的问题就会轻松很多,不然的话你就会一直困与找不到奔溃的地方,然后耽误很多时间。

这里我就简单说一下接下来我们要用的这个崩溃日志输出接口。

E4A程序中,左边面板:工程>接口,右键创建接口函数,函数名:CrashHandler


创建完毕后复制下面的代码粘贴到CrashHandler

  1. package com.e4a.runtime.api;//包名必须固定为这个,不能自己修改

  2. import com.e4a.runtime.annotations.SimpleFunction;
  3. import com.e4a.runtime.annotations.SimpleObject;
  4. import com.e4a.runtime.annotations.UsesPermissions;

  5. import com.e4a.runtime.应用操作;//可以引用E4A支持库中已经存在的类
  6. import com.e4a.runtime.android.mainActivity;

  7. import android.widget.Toast;
  8. import java.io.File;  
  9. import java.io.FileOutputStream;  
  10. import java.io.PrintWriter;  
  11. import java.io.StringWriter;  
  12. import java.io.Writer;  
  13. import java.lang.Thread.UncaughtExceptionHandler;  
  14. import java.lang.reflect.Field;  
  15. import java.text.DateFormat;  
  16. import java.text.SimpleDateFormat;  
  17. import java.util.Date;  
  18. import java.util.HashMap;  
  19. import java.util.Map;  
  20.   
  21. import android.content.Context;  
  22. import android.content.pm.PackageInfo;  
  23. import android.content.pm.PackageManager;  
  24. import android.content.pm.PackageManager.NameNotFoundException;  
  25. import android.os.Build;  
  26. import android.os.Environment;  
  27. import android.os.Looper;  
  28. import android.util.Log;  
  29. import android.widget.Toast;

  30. @UsesPermissions(permissionNames = "android.permission.INTERNET")//安卓权限标记,如果接口函数中需要额外的安卓权限,可在此填写,多个权限可以用逗号隔开
  31. @SimpleObject
  32. public class CrashHandler implements UncaughtExceptionHandler{

  33.      public static final String TAG = "CrashHandler";  
  34.       
  35.     //系统默认的UncaughtException处理类   
  36.     private Thread.UncaughtExceptionHandler mDefaultHandler;  
  37.     //CrashHandler实例  
  38.     private static CrashHandler INSTANCE = new CrashHandler();  
  39.     //程序的Context对象  
  40.     private Context mContext;  
  41.     //用来存储设备信息和异常信息  
  42.     private Map<String, String> infos = new HashMap<String, String>();  
  43.   
  44.     //用于格式化日期,作为日志文件名的一部分  
  45.     private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");  
  46.   
  47.     /** 保证只有一个CrashHandler实例 */  
  48.     private CrashHandler() {  
  49.     }  
  50.   
  51.     /** 获取CrashHandler实例 ,单例模式 */  
  52.     public static CrashHandler getInstance() {  
  53.         return INSTANCE;  
  54.     }  
  55.   
  56.     /**
  57.      * 初始化
  58.      *  
  59.      * @param context
  60.      */  
  61.     public void init(Context context) {  
  62.         mContext = context;  
  63.         //获取系统默认的UncaughtException处理器  
  64.         mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();  
  65.         //设置该CrashHandler为程序的默认处理器  
  66.         Thread.setDefaultUncaughtExceptionHandler(this);  
  67.     }  
  68.   
  69.     /**
  70.      * 当UncaughtException发生时会转入该函数来处理
  71.      */  
  72.     @Override  
  73.     public void uncaughtException(Thread thread, Throwable ex) {  
  74.         if (!handleException(ex) && mDefaultHandler != null) {  
  75.             //如果用户没有处理则让系统默认的异常处理器来处理  
  76.             mDefaultHandler.uncaughtException(thread, ex);  
  77.         } else {  
  78.             try {  
  79.                 Thread.sleep(3000);  
  80.             } catch (InterruptedException e) {  
  81.                 Log.e(TAG, "error : ", e);  
  82.             }  
  83.             //退出程序  
  84.             android.os.Process.killProcess(android.os.Process.myPid());  
  85.             System.exit(1);  
  86.         }  
  87.     }  
  88.   
  89.     /**
  90.      * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
  91.      *  
  92.      * @param ex
  93.      * @return true:如果处理了该异常信息;否则返回false.
  94.      */  
  95.     private boolean handleException(Throwable ex) {  
  96.         if (ex == null) {  
  97.             return false;  
  98.         }  
  99.         //使用Toast来显示异常信息  
  100.         new Thread() {  
  101.             @Override  
  102.             public void run() {  
  103.                 Looper.prepare();  
  104.                 Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_LONG).show();  
  105.                 Looper.loop();  
  106.             }  
  107.         }.start();  
  108.         //收集设备参数信息   
  109.         collectDeviceInfo(mContext);  
  110.         //保存日志文件   
  111.         saveCrashInfo2File(ex);  
  112.         return true;  
  113.     }  
  114.       
  115.     /**
  116.      * 收集设备参数信息
  117.      * @param ctx
  118.      */  
  119.     public void collectDeviceInfo(Context ctx) {  
  120.         try {  
  121.             PackageManager pm = ctx.getPackageManager();  
  122.             PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);  
  123.             if (pi != null) {  
  124.                 String versionName = pi.versionName == null ? "null" : pi.versionName;  
  125.                 String versionCode = pi.versionCode + "";  
  126.                 infos.put("versionName", versionName);  
  127.                 infos.put("versionCode", versionCode);  
  128.             }  
  129.         } catch (NameNotFoundException e) {  
  130.             Log.e(TAG, "an error occured when collect package info", e);  
  131.         }  
  132.         Field[] fields = Build.class.getDeclaredFields();  
  133.         for (Field field : fields) {  
  134.             try {  
  135.                 field.setAccessible(true);  
  136.                 infos.put(field.getName(), field.get(null).toString());  
  137.                 Log.d(TAG, field.getName() + " : " + field.get(null));  
  138.             } catch (Exception e) {  
  139.                 Log.e(TAG, "an error occured when collect crash info", e);  
  140.             }  
  141.         }  
  142.     }  
  143.   
  144.     /**
  145.      * 保存错误信息到文件中
  146.      *  
  147.      * @param ex
  148.      * @return  返回文件名称,便于将文件传送到服务器
  149.      */  
  150.     private String saveCrashInfo2File(Throwable ex) {  
  151.          
  152.         StringBuffer sb = new StringBuffer();  
  153.         for (Map.Entry<String, String> entry : infos.entrySet()) {  
  154.             String key = entry.getKey();  
  155.             String value = entry.getValue();  
  156.             sb.append(key + "=" + value + "\n");  
  157.         }  
  158.          
  159.         Writer writer = new StringWriter();  
  160.         PrintWriter printWriter = new PrintWriter(writer);  
  161.         ex.printStackTrace(printWriter);  
  162.         Throwable cause = ex.getCause();  
  163.         while (cause != null) {  
  164.             cause.printStackTrace(printWriter);  
  165.             cause = cause.getCause();  
  166.         }  
  167.         printWriter.close();  
  168.         String result = writer.toString();  
  169.         sb.append(result);  
  170.         try {  
  171.             long timestamp = System.currentTimeMillis();  
  172.             String time = formatter.format(new Date());  
  173.             String fileName = "crash-" + time + "-" + timestamp + ".log";  
  174.             
  175.                 String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/eruyi/";  
  176.                 File dir = new File(path);  
  177.                 if (!dir.exists()) {  
  178.                     dir.mkdirs();  
  179.                 }  
  180.                 FileOutputStream fos = new FileOutputStream(path + fileName);  
  181.                 fos.write(sb.toString().getBytes());  
  182.                 fos.close();  
  183.               
  184.             return fileName;  
  185.         } catch (Exception e) {  
  186.             Log.e(TAG, "an error occured while writing file...", e);  
  187.         }  
  188.         return null;  
  189.     }  

  190. }
复制代码
然后再右键 创建全局应用(APPlication)
复制粘贴以下代码
  1. package com.e4a.runtime.android;//请勿修改此包名

  2. import android.app.Application;
  3. import com.e4a.runtime.api.CrashHandler;
  4. public class 全局应用 extends E4Aapplication {

  5.   @Override
  6.     public void onCreate() {
  7.         super.onCreate();
  8.         CrashHandler crashHandler = CrashHandler.getInstance();  
  9.         crashHandler.init(getApplicationContext());  
  10.     }

  11. }
复制代码


这样你的APP编译后,如果出现崩溃现象,就会将崩溃的原因写入到你的手机里:默认写在手机里的:eruyi目录中,这个目录大家也可以自行更改

如果这样你还是不懂的话就下载例子看看吧。

崩溃日志接口.e4a (151.65 KB, 下载次数: 114, 售价: 2 易积分)

评分

参与人数 2易积分 +4 收起 理由
初学者小萌妹 -1 内容已失效
易如意 + 5 新技能已get√

查看全部评分

易如意中文编程学习交流论坛有你更精彩~
回复

使用道具 举报

12

主题

876

积分

0

精华

用户组 

易积分
3196
热心
6
好评
1

热心会员活跃会员

发表于 2018-5-12 00:51:38 | 显示全部楼层
新技能  给力  
易如意中文编程学习交流论坛有你更精彩~
回复

使用道具 举报

12

主题

992

积分

0

精华

用户组 

易积分
6388
热心
0
好评
0

活跃会员

发表于 2019-6-2 22:09:05 | 显示全部楼层
关键是这日志也看不懂呀
易如意中文编程学习交流论坛有你更精彩~
回复

使用道具 举报

0

主题

8

积分

0

精华

用户组 

易积分
17
热心
0
好评
0
发表于 2019-8-10 08:55:18 | 显示全部楼层
可是我也看不懂崩溃日志啊。。
易如意中文编程学习交流论坛有你更精彩~
回复

使用道具 举报

0

主题

132

积分

0

精华

用户组 

易积分
80
热心
0
好评
0
发表于 2019-10-13 22:47:39 | 显示全部楼层
太好用了,这E4A做的app经常崩溃都把我搞崩溃了,使用之后确实能够很快的定位到故障点,直接定位到那个页面的哪一行代码,一些认为不会出错的地方也能够直接找到
易如意中文编程学习交流论坛有你更精彩~
回复

使用道具 举报

10

主题

506

积分

0

精华

用户组 

易积分
105
热心
0
好评
1
发表于 2019-10-14 00:41:24 来自手机 | 显示全部楼层
什么嘛这是看不懂
易如意中文编程学习交流论坛有你更精彩~
回复

使用道具 举报

19

主题

673

积分

0

精华

用户组 

易积分
296
热心
0
好评
0

活跃会员

发表于 2019-12-19 15:17:11 | 显示全部楼层
薅的
易如意中文编程学习交流论坛有你更精彩~
回复

使用道具 举报

0

主题

68

积分

0

精华

用户组 

易积分
169
热心
0
好评
0
发表于 2019-12-19 18:34:29 | 显示全部楼层
创建完毕后复制下面的代码粘贴到CrashHandler中
易如意中文编程学习交流论坛有你更精彩~
回复

使用道具 举报

2

主题

110

积分

0

精华

用户组 

易积分
197
热心
0
好评
0
发表于 2019-12-29 18:25:40 | 显示全部楼层
经测试会让软件卡比
易如意中文编程学习交流论坛有你更精彩~
回复

使用道具 举报

1

主题

155

积分

0

精华

用户组 

易积分
93
热心
0
好评
0
发表于 2019-12-30 08:58:21 | 显示全部楼层
易如意中文编程学习交流论坛有你更精彩~
易如意中文编程学习交流论坛有你更精彩~
回复

使用道具 举报

QQ|sitemap|免责声明|RGB颜色对照表|手机版|小黑屋| 易如意 - E4A中文编程学习交流论坛

GMT+8, 2024-4-27 06:25 , Processed in 0.071578 second(s), 44 queries .

Powered by Discuz! X3.4

© 2001-2018 eruyi.cn

返回顶部