MasterofProject

Android in dealing with the collapse of the exception

label Androidexception handlingapplication program
95 people read comment(0) Collection report
Classification:
Turn from the original: http://prog3.com/sbdm/blog/liuhe688/article/details/6584143, thanks to share!

As we all know, now the mobile phone version of Android system installation and equipment are installed to a good mobile phone might collapse phenomenon run in the simulator, the individual developer could not buy all the equipment by debugging, so after the program released out, if there is a breakdown phenomenon, developers should be timely access to the collapse of the information on the device, for the repair of bug under a version of great help, so today is to introduce how to collect relevant information and equipment parameters specific exception information in the event of a program crash, and send the information to the server for the developer to analyze and debug the program.

We first set up a crash project, the project structure as shown:

In the MainActivity.java code, the code is written in this way:

[java] View PlainCopy
  1. PackageCom.scott.crash;
  2.   
  3. ImportAndroid.app.Activity;
  4. ImportAndroid.os.Bundle;
  5.   
  6. Public ClassMainActivityExtendsActivity {
  7.   
  8.     PrivateS String;
  9.       
  10.     @Override  
  11.     Public VoidOnCreate (savedInstanceState Bundle) {
  12.         Super.onCreate (savedInstanceState);
  13. System.out.println (s.equals ("String any"));
  14. }
  15. }

We have deliberately created a potential runtime exception that occurs when we run the program:

After the exception of the software is not caught, the system will pop up the default mandatory shutdown dialog box.

Of course, we do not want users to see this phenomenon, it is a blow to the user's mind, but also for the repair of our bug is no help. We need software has a global exception trap when there is a we found no abnormalities, catch the exception and the exception information recorded, upload to the server public development of this analysis, the specific reasons for unusual.

Next we come to realize this mechanism, but first we have to understand the following two categories: android.app.Application and java.lang.Thread.UncaughtExceptionHandler.

Application: used to manage the global state of the application. At the start of the application Application will be created first, and then will be based on the situation (Intent) to start the corresponding Activity and Service. In this example, the custom enhanced version of the Application is not registered with the exception handler.

Thread.UncaughtExceptionHandler: thread does not capture exception handler, used to handle an exception that is not captured. If there is no exception to the program, the default will pop up the system in the forced shutdown dialog box. We need to implement this interface, and register as a program in which the default does not capture exception handling. In this way, when an exception occurs, you can do some personalized exception handling operations.

We have just seen in the structure of the project to see the CrashHandler.java Thread.UncaughtExceptionHandler, so that we used to deal with the main members of the non capture exception, the code is as follows:

[java] View PlainCopy
  1. PackageCom.scott.crash;
  2.   
  3. ImportJava.io.File;
  4. ImportJava.io.FileOutputStream;
  5. ImportJava.io.PrintWriter;
  6. ImportJava.io.StringWriter;
  7. ImportJava.io.Writer;
  8. ImportJava.lang.Thread.UncaughtExceptionHandler;
  9. ImportJava.lang.reflect.Field;
  10. ImportJava.text.DateFormat;
  11. ImportJava.text.SimpleDateFormat;
  12. ImportJava.util.Date;
  13. ImportJava.util.HashMap;
  14. ImportJava.util.Map;
  15.   
  16. ImportAndroid.content.Context;
  17. ImportAndroid.content.pm.PackageInfo;
  18. ImportAndroid.content.pm.PackageManager;
  19. ImportAndroid.content.pm.PackageManager.NameNotFoundException;
  20. ImportAndroid.os.Build;
  21. ImportAndroid.os.Environment;
  22. ImportAndroid.os.Looper;
  23. ImportAndroid.util.Log;
  24. ImportAndroid.widget.Toast;
  25.   
  26. / * * 
  27. * uncaughtException处理类,当程序发生捕获的异常的时候,有该类来接管程序,并记录发送错误报告。 
  28. * 
  29. * @作者用户 
  30. * 
  31. *  
  32. 公共 crashhandler实现了uncaughtexceptionhandler {
  33.       
  34.     公共 静态 最后字符串标记=“crashhandler”
  35.       
  36.     / /系统默认的uncaughtException处理类  
  37.     私人thread.uncaughtexceptionhandler mdefaulthandler;
  38.     / / crashhandler实例  
  39.     私人 静态crashhandler实例=新的crashhandler();
  40.     / /程序的语境对象  
  41.     私人背景mcontext;
  42.     / /用来存储设备信息和异常信息  
  43.     私人图<字符串,字符串>信息=新的HashMap <字符串,字符串>();
  44.   
  45.     / /用于格式化日期,作为日志文件名的一部分  
  46.     私人DateFormat格式化程序=新的不是(“yyyy-mm-dd HH毫米SS”);
  47.   
  48.     保证只有一个crashhandler实例/ * * /  
  49.     私人crashhandler() {
  50. }
  51.   
  52.     / * *获取crashhandler实例,单例模式*/  
  53.     公共 静态crashhandler getinstance() {
  54.         返回实例;
  55. }
  56.   
  57.     * * * * 
  58. *初始化 
  59. * 
  60. * @param语境 
  61. *  
  62.     公共 无效init(语境){
  63. mcontext =语境;
  64.         / /获取系统默认的uncaughtException处理器  
  65. mdefaulthandler = getdefaultuncaughtexceptionhandler()线程;
  66.         / /设置该crashhandler为程序的默认处理器  
  67. setdefaultuncaughtexceptionhandler(线程。);
  68. }
  69.   
  70.     * * * * 
  71. *当uncaughtException发生时会转入该函数来处理 
  72. *  
  73.     “重写”  
  74.     公共 无效uncaughtException(螺纹,Throwable EX){
  75.         如果(!handleexception(Ex)和mdefaulthandler!=){
  76.             / /如果用户没有处理则让系统默认的异常处理器来处理  
  77. mdefaulthandler uncaughtException(线、前);
  78. }其他的{
  79.             试试 看{
  80. 睡觉(三千);
  81. }抓住(InterruptedException e){
  82. 日志:电子标签,“错误:”,电子;
  83. }
  84.             / /退出程序  
  85. Android操作系统。过程。killprocess(Android OS的过程。mypid());
  86. 系统。);
  87. }
  88. }
  89.   
  90.     * * * * 
  91. *自定义错误处理,收集错误信息发送错误报告等操作均在此完成。 
  92. * 
  93. * @param前 
  94. * @返回true:如果处理了该异常信息;否则返回假。 
  95. *  
  96.     私人 布尔handleexception(Throwable EX){
  97.         如果(前= =){
  98.             返回 
  99. }
  100.         / /使用吐司来显示异常信息  
  101.         新的thread() {
  102.             “重写”  
  103.             公共 无效run() {
  104. prepare()活套;
  105. maketext(mcontext干杯,“很抱歉,程序出现异常,即将退出。”,烤面包。length_long show());
  106. loop()活套;
  107. }
  108. start() };
  109.         / /收集设备参数信息  
  110. collectdeviceinfo(mcontext);
  111.         / /保存日志文件  
  112. savecrashinfo2file(前);
  113.         返回 真正的
  114. }
  115.       
  116.     * * * * 
  117. *收集设备参数信息 
  118. * @param CTX 
  119. *  
  120.     公共 无效collectdeviceinfo(上下文CTX){
  121.         试试 看{
  122. getpackagemanager() PackageManager PM = CTX;
  123. packageInfo PI = PM。得到自己的包名(CTX。getpackagename(),PackageManager. get_activities);
  124.             如果(皮!=){
  125. 字符串versionName = pi.versionname = =“空”:pi.versionname;
  126. 字符串versioncode = pi.versioncode +“”
  127. 把(信息。“versionName”versionName);
  128. 把(信息。“versioncode”,versioncode);
  129. }
  130. }抓住(namenotfoundexception e){
  131. 日志:电子标签,“收集包装信息时出现错误”,电子;
  132. }
  133. 田野=建造。getdeclaredfields();
  134.         对于(字段字段:字段){
  135.             试试 看{
  136. 领域。setAccessible(真正的);
  137. 信息。把(领域。getname(),得到(领域。tostring()));
  138. 日志。D(标签领域。getname() +“:”+字段。);
  139. }抓住(例外){
  140. 日志:电子标签,“收集崩溃信息时发生错误”,电子;
  141. }
  142. }
  143. }
  144.   
  145.     * * * * 
  146. *保存错误信息到文件中 
  147. * 
  148. * @param前 
  149. * @返回返回文件名称,便于将文件传送到服务器 
  150. *  
  151.     私人字符串savecrashinfo2file(Throwable EX){
  152.           
  153. StringBuffer某人新的stringbuffer();
  154.         对于(地图。进入<字符串,字符串>输入:信息。entryset()){
  155. getkey()字符串键=进入;
  156. 字符串值=条目。getvalue();
  157. 追加(密钥+“=”+值+“\”);
  158. }
  159.           
  160. 作家作家=新的stringwriter();
  161. PrintWriter PrintWriter =新的PrintWriter(作家);
  162. ex.printstacktrace(PrintWriter);
  163. 如getcause() Throwable原因=;
  164.         (原因!=){
  165. printStackTrace(PrintWriter)的原因;
  166. 原因=原因。getcause();
  167. }
  168. PrintWriter。();
  169. 结果字符串=作家。tostring();
  170. 附加(结果);
  171.         试试看{
  172.             时间戳currenttimemillis() =系统;
  173. 字符串格式(时间=格式化程序。新的());
  174. 字符串文件名=“崩溃”+时间+“-”+时间+“日志”
  175.             如果(环境。getexternalstoragestate()。等于(环境。media_mounted)){
  176. 字符串路径=“/ SD卡/碰撞/”
  177. 文件目录=新的文件(路径);
  178.                 如果(!迪尔。exists()){
  179. mkdirs()目录;
  180. }
  181. FileOutputStream FOS =新的FileOutputStream(路径+文件名);
  182. FOS。写(某人tostring()。getbytes());
  183. FOS。();
  184. }
  185.             返回文件名;
  186. }抓住(例外){
  187. 日志:电子标签,“写入文件时发生错误…”,电子;
  188. }
  189.         返回 
  190. }
  191. }

在收集异常信息时,朋友们也可以使用性质,因为性能有一个很便捷的方法性质。商店(OutputStream,字符串的评论),用来将性能实例中的键值对外输到输出流中,但是在使用的过程中发现生成的文件中异常信息打印在同一行,看起来极为费劲,所以换成地图来存放这些信息,然后生成文件时稍加了些操作。

完成这个crashhandler后,我们需要在一个应用环境中让其运行,为此,我们继承Android。应用。应用,添加自己的代码,crashapplication Java代码如下:

[爪哇] 观 平原复制
  1. com.scott.crash;
  2.   
  3. 进口android.app.application;
  4.   
  5. 公共 crashapplication延伸应用{
  6.     “重写”  
  7.     公共 无效oncreate() {
  8.         好极了oncreate();
  9. crashhandler crashhandler = crashhandler。getinstance();
  10. crashhandler init(getapplicationcontext());
  11. }
  12. }

最后,为了让我们的crashapplication取代Android。应用。应用的地位,在我们的代码中生效,我们需要修改AndroidManifest.xml:

[网页] 观 平原复制
  1. <应用 安卓:名字=”。crashapplication”>  
  2. < /应用>  

因为我们上面的crashhandler中,遇到异常后要保存设备参数和具体异常信息到SD卡,所以我们需要在AndroidManifest. xml中加入读写SD卡权限:

[网页] 观 平原复制
  1. <使用权限 安卓:名字=“Android的许可。write_external_storage”/ >  

搞定了上边的步骤之后,我们来运行一下这个项目:

看以看到,并不会有强制关闭的对话框出现了,取而代之的是我们比较有好的提示信息。

然后看一下SD卡生成的文件:



用文本编辑器打开日志文件,看一段日志信息:

[爪哇] 观 平原复制
  1. cpu_abi = armeabi
  2. cpu_abi2 =未知
  3. ID = frf91
  4. 制造商=未知
  5. 品牌=通用
  6. 类型=英格
  7. ......
  8. 致:java.lang.nullpointerexception
  9. COM。史葛。崩溃。MainActivity onCreate(mainactivity.java:十三
  10. 在Android应用程序。callactivityoncreate(instrumentation.java仪表:一千零四十七
  11. 在Android应用程序。activitythread performlaunchactivity(activitythread.java:二千六百二十七
  12. 十一更多

这些信息对于开发者来说帮助极大,所以我们需要将此日志文件上传到服务器,有关文件上传的技术,请参照Android中使用HTTP服务相关介绍。

不过在使用HTTP服务之前,需要确定网络畅通,我们可以使用下面的方式判断网络是否可用:

[爪哇] 观 平原复制
  1. * * * * 
  2. *网络是否可用 
  3. * 
  4. * @param语境 
  5. * @返回 
  6. *  
  7.     公共 静态 布尔isnetworkavailable(语境){
  8. connectivitymanager MGR =(connectivitymanager)背景。getSystemService(上下文。connectivity_service);
  9. networkinfo [ ]信息=经理getallnetworkinfo();
  10.         如果(信息!=){
  11.             对于int我=;我的<< info.length;i++){
  12.                 如果(信息[我]。getstate() = = networkinfo。状态。连接){
  13.                     返回 真正的
  14. }
  15. }
  16. }
  17.         返回 
  18. }
猜你在找
查看评论
*以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:51397次
    • 积分:二千三百二十六
    • 等级:
    • 排名:9595名第
    • 原创:187篇
    • 转载:37篇
    • 译文:1篇
    • 评论:13条
    文章分类
    文章存档
    最新评论