android关于异常退出的学习
2012-06-13 14:13
435 查看
学习来源:http://blog.csdn.net/liuhe688/article/details/6584143
主界面类:CrashHandleDemo1Activity
import android.app.Activity;
import android.os.Bundle;
/**
* @author Administrator
*用于学习异常处理的接受和写入文件(如果有需要可以想服务器发送消息的操作)
*/
public class CrashHandleDemo1Activity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//开发人员自己接受并且处理了异常,那么在系统就不会得到显示
// try
// {
// String string1 = null;
// string1.equals("");
// }
// catch (Exception e)
// {
// e.printStackTrace();
// }
// System.out.println("开发人员没有处理异常");
//开发人员没有处理异常
String string = null;
string.equals("");
System.out.println("end");
}
}
MyCrashHandler.java
public class MyCrashHandler implements UncaughtExceptionHandler
{
// 系统默认的UncaughtException处理类
Thread.UncaughtExceptionHandler exceptionHandler;
// 上下文环境
Context context;
// 存放消息
HashMap<String, String> infos = new HashMap<String, String>();
// 单列模式
private static MyCrashHandler handler = new MyCrashHandler();
private MyCrashHandler()
{
}
public static MyCrashHandler getInstance()
{
return handler;
}
//初始化操作
public void init(Context context)
{
this.context = context;
//获得系统默认的异常处理方法
exceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
//设置系统自带异常处理方法为本类
Thread.setDefaultUncaughtExceptionHandler(this);
}
/* Throwable的说明:简单的认知就是Throwable就是exception的父类
* The superclass of all classes which can be thrown by the virtual machine.
The two direct subclasses are recoverable exceptions (Exception) and
unrecoverable errors (Error). This class provides common methods for accessing a
string message which provides extra information about the circumstances in which
the Throwable was created (basically an error message in most cases), and for
saving a stack trace (that is, a record of the call stack at a particular point
in time) which can be printed later.
A Throwable can also include a cause, which is a nested Throwable that represents
the original problem that led to this Throwable. It is often used for wrapping
various types oferrors into a common Throwable without losing the detailed original
error information. When printing the stack trace, the trace of the cause is included.
*/
@Override
public void uncaughtException(Thread thread, Throwable ex)
{
if (!handleException(ex) && exceptionHandler != null)
{
//当ex为空的时候,调用此方法(如果用户自己处理try-catch操作,也不会运行到此界面)
//调用系统默认的处理方法
exceptionHandler.uncaughtException(thread, ex);
}// if
else
{
try
{
Thread.sleep(3000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
// 退出程序
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}// else
}
// 当有异常的时候,ex不等于null,返回false
private boolean handleException(Throwable ex)
{
if (ex == null)
{
return false;
}
//有异常
new Thread()
{
@Override
public void run()
{
//Looper用于封装了android线程中的消息循环,默认情况下一个线程是不存在消息循环
//(message loop)的,需要调用Looper.prepare()来给线程创建一个消息循环,
//调用Looper.loop()来使消息循环起作用,从消息队列里取消息,处理消息。
Looper.prepare();
Toast.makeText(context, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_LONG).show();
Looper.loop();
}
}.start();
//手机设备信息
collectDeviceInfo(context);
//保存到文件sdcard中区
wirteToFile(ex);
return true;
}
private void collectDeviceInfo(Context context)
{
/* PackageManager相关和ActivitManager相关。
PackageManager相关
本类API是对所有基于加载信息的数据结构的封装,包括以下功能:
安装,卸载应用
查询permission相关信息
查询Application相关信息(application,activity,receiver,service,provider及相应属性等)
查询已安装应用
增加,删除permission
清除用户数据、缓存,代码段等
非查询相关的API需要特定的权限,具体的API请参考SDK文档。
ActivityManager相关
本类API是对运行时管理功能和运行时数据结构的封装,包括以下功能
激活/去激活activity
注册/取消注册动态接受intent
发送/取消发送intent
activity生命周期管理(暂停,恢复,停止,销毁等)
activity task管理(前台->后台,后台->前台,最近task查询,运行时task查询)
激活/去激活service
激活/去激活provider等*/
//获得包管理器
PackageManager pi = context.getPackageManager();
try
{
//获得这个应用的包的信息
PackageInfo info = pi.getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null)
{
//版本和名字
String vName = info.versionName == null ? "null" : info.versionName;
String vCode = info.versionCode + "";
//写入
infos.put("versionName", vName);
infos.put("versionCode", vCode);
}
}
catch (NameNotFoundException e)
{
e.printStackTrace();
}
/*Field:
* This class represents a field字段. Information about the field can be accessed,
* and the field's value can be accessed dynamically.*/
// Build:
// Information about the current build, extracted from system properties.
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields)
{
try
{
field.setAccessible(true);
System.out.println("field.getName()="+ field.get(null).toString());
infos.put(field.getName(), field.get(null).toString());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
//写入到文件中区
private void wirteToFile(Throwable ex)
{
StringBuffer sb = new StringBuffer();
for (Map.Entry<String, String> map : infos.entrySet())
{
String key = map.getKey();
String value = map.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 reString = writer.toString();
sb.append(reString);
try
{
long time = System.currentTimeMillis();
String fileName = "crash-" + time + ".log";
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
String path = "/sdcard/crash";
File dir = new File(path);
if (!dir.exists())
{
dir.mkdirs();
}
FileOutputStream stream = new FileOutputStream(path + fileName);
stream.write(sb.toString().getBytes());
stream.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
MyAppliction.java
/**
* @author Administrator
*重写Application类,用于设置异常处理
*/
public class MyAppliction extends Application
{
@Override
public void onCreate()
{
super.onCreate();
//通过单利模式,获得异常处理类
MyCrashHandler handler = MyCrashHandler.getInstance();
//初始化
handler.init(getApplicationContext());
}
}
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ljz.crash.demo1"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:name=".MyAppliction"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".CrashHandleDemo1Activity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
主界面类:CrashHandleDemo1Activity
import android.app.Activity;
import android.os.Bundle;
/**
* @author Administrator
*用于学习异常处理的接受和写入文件(如果有需要可以想服务器发送消息的操作)
*/
public class CrashHandleDemo1Activity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//开发人员自己接受并且处理了异常,那么在系统就不会得到显示
// try
// {
// String string1 = null;
// string1.equals("");
// }
// catch (Exception e)
// {
// e.printStackTrace();
// }
// System.out.println("开发人员没有处理异常");
//开发人员没有处理异常
String string = null;
string.equals("");
System.out.println("end");
}
}
MyCrashHandler.java
public class MyCrashHandler implements UncaughtExceptionHandler
{
// 系统默认的UncaughtException处理类
Thread.UncaughtExceptionHandler exceptionHandler;
// 上下文环境
Context context;
// 存放消息
HashMap<String, String> infos = new HashMap<String, String>();
// 单列模式
private static MyCrashHandler handler = new MyCrashHandler();
private MyCrashHandler()
{
}
public static MyCrashHandler getInstance()
{
return handler;
}
//初始化操作
public void init(Context context)
{
this.context = context;
//获得系统默认的异常处理方法
exceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
//设置系统自带异常处理方法为本类
Thread.setDefaultUncaughtExceptionHandler(this);
}
/* Throwable的说明:简单的认知就是Throwable就是exception的父类
* The superclass of all classes which can be thrown by the virtual machine.
The two direct subclasses are recoverable exceptions (Exception) and
unrecoverable errors (Error). This class provides common methods for accessing a
string message which provides extra information about the circumstances in which
the Throwable was created (basically an error message in most cases), and for
saving a stack trace (that is, a record of the call stack at a particular point
in time) which can be printed later.
A Throwable can also include a cause, which is a nested Throwable that represents
the original problem that led to this Throwable. It is often used for wrapping
various types oferrors into a common Throwable without losing the detailed original
error information. When printing the stack trace, the trace of the cause is included.
*/
@Override
public void uncaughtException(Thread thread, Throwable ex)
{
if (!handleException(ex) && exceptionHandler != null)
{
//当ex为空的时候,调用此方法(如果用户自己处理try-catch操作,也不会运行到此界面)
//调用系统默认的处理方法
exceptionHandler.uncaughtException(thread, ex);
}// if
else
{
try
{
Thread.sleep(3000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
// 退出程序
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}// else
}
// 当有异常的时候,ex不等于null,返回false
private boolean handleException(Throwable ex)
{
if (ex == null)
{
return false;
}
//有异常
new Thread()
{
@Override
public void run()
{
//Looper用于封装了android线程中的消息循环,默认情况下一个线程是不存在消息循环
//(message loop)的,需要调用Looper.prepare()来给线程创建一个消息循环,
//调用Looper.loop()来使消息循环起作用,从消息队列里取消息,处理消息。
Looper.prepare();
Toast.makeText(context, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_LONG).show();
Looper.loop();
}
}.start();
//手机设备信息
collectDeviceInfo(context);
//保存到文件sdcard中区
wirteToFile(ex);
return true;
}
private void collectDeviceInfo(Context context)
{
/* PackageManager相关和ActivitManager相关。
PackageManager相关
本类API是对所有基于加载信息的数据结构的封装,包括以下功能:
安装,卸载应用
查询permission相关信息
查询Application相关信息(application,activity,receiver,service,provider及相应属性等)
查询已安装应用
增加,删除permission
清除用户数据、缓存,代码段等
非查询相关的API需要特定的权限,具体的API请参考SDK文档。
ActivityManager相关
本类API是对运行时管理功能和运行时数据结构的封装,包括以下功能
激活/去激活activity
注册/取消注册动态接受intent
发送/取消发送intent
activity生命周期管理(暂停,恢复,停止,销毁等)
activity task管理(前台->后台,后台->前台,最近task查询,运行时task查询)
激活/去激活service
激活/去激活provider等*/
//获得包管理器
PackageManager pi = context.getPackageManager();
try
{
//获得这个应用的包的信息
PackageInfo info = pi.getPackageInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null)
{
//版本和名字
String vName = info.versionName == null ? "null" : info.versionName;
String vCode = info.versionCode + "";
//写入
infos.put("versionName", vName);
infos.put("versionCode", vCode);
}
}
catch (NameNotFoundException e)
{
e.printStackTrace();
}
/*Field:
* This class represents a field字段. Information about the field can be accessed,
* and the field's value can be accessed dynamically.*/
// Build:
// Information about the current build, extracted from system properties.
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields)
{
try
{
field.setAccessible(true);
System.out.println("field.getName()="+ field.get(null).toString());
infos.put(field.getName(), field.get(null).toString());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
//写入到文件中区
private void wirteToFile(Throwable ex)
{
StringBuffer sb = new StringBuffer();
for (Map.Entry<String, String> map : infos.entrySet())
{
String key = map.getKey();
String value = map.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 reString = writer.toString();
sb.append(reString);
try
{
long time = System.currentTimeMillis();
String fileName = "crash-" + time + ".log";
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
String path = "/sdcard/crash";
File dir = new File(path);
if (!dir.exists())
{
dir.mkdirs();
}
FileOutputStream stream = new FileOutputStream(path + fileName);
stream.write(sb.toString().getBytes());
stream.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
MyAppliction.java
/**
* @author Administrator
*重写Application类,用于设置异常处理
*/
public class MyAppliction extends Application
{
@Override
public void onCreate()
{
super.onCreate();
//通过单利模式,获得异常处理类
MyCrashHandler handler = MyCrashHandler.getInstance();
//初始化
handler.init(getApplicationContext());
}
}
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ljz.crash.demo1"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:name=".MyAppliction"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".CrashHandleDemo1Activity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
相关文章推荐
- android关于异常退出的学习
- Android学习札记39:关于安全退出已创建多个Activity的应用(2)
- Android开发学习笔记,修改Activity名称后,导致程序打开该Activity时异常退出
- Android学习札记38:关于安全退出已创建多个Activity的应用(1)
- android关于退出的学习
- Android学习札记40:关于安全退出已创建多个Activity的应用(3)
- 【Android学习】关于Android4.4沉浸模式的进入和退出时系统栏状态栏遮盖问题
- 【Android】关于PhotoView频繁缩小异常退出的BUG
- 关于android自定义控件Topbar的学习
- Android学习---关于布局的一些东西
- JAVA学习笔记_关于异常机制处理问题
- 关于Android中保存activity的状态的几点学习笔记
- 关于PHP-Zend framework2 框架 学习过程。 阅前须知: ZF2中的配置文件是可以静态文件配置来注册和通过相关函数动态注册。 1.EventManager(事件驱动),关于事件驱动,在ZF2相关资料没有详细说明,可以参考ANDROID的事件驱动,MFC的消息响应/事件驱动。
- 关于android.view.WindowLeaked异常的解决方案
- osg for android 学习之八:关于StateSet
- Android中关于JNI 的学习(五)在C文件中使用LogCat
- 关于Android ant build的学习
- Android开发学习之路-- 关于服务Service
- 不错的关于VOIP ---- Android Sip学习
- Android学习:Could not find XXX.apk!异常解决