【Android开发经验】我们要友好的告诉用户,程序要崩溃了
转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992
尽管我们的程序在正式上线之前,都会经过严格的測试。从而保证程序的健壮性和良好的用户体验,可是,一个人的測试或者是几个人的測试团队,都不能和上万甚至数十万的用户相比。因此。前期刚上线的程序在用户手里被玩崩了,也是非经常见的事,可是。假设我们不做特殊处理。系统自带的程序崩溃提示真的太吓人了,用户看到之后会不知所措。因此,我们须要一个解决方式。就是在程序即将崩溃的时候。给用户一个更加友好的提示。来告诉他,程序立即要崩溃了。
就像是以下这样:
这样是不是更加友好一点呢?
以下解说怎样实现。
假设要实现这样的功能。我们须要关注的是Thread类里面的一个接口,UncaughtExceptionHandler,另一个设置Thread.setDefaultUncaughtExceptionHandler(),这两个东西究竟是干嘛的呢?
UncaughtExceptionHandler 这个接口是当Thread由于未被捕获的异常而要被终止的时候。会被调用的回调接口。
而Thread.setDefaultUncaughtExceptionHandler()这种方法,则是设置当线程由于未捕获到异常而突然终止,而且没有为该线程定义其它处理程序时所调用的默认处理程序。
因此,假设我们想自己处理程序要崩溃时的处理逻辑,我们仅仅须要实现UncaughtExceptionHandler接口,并调用Thread.setDefaultUncaughtExceptionHandler()设置就可以。
以下是演示样例代码
首先。先给出上面效果图中的Activity的代码
package com.example.exceptiondemo; import android.app.Activity;
import android.os.Bundle;
import android.view.View; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 注冊默认的未捕捉异常处理类
Thread.setDefaultUncaughtExceptionHandler(AppException
.getAppExceptionHandler());
AppManager.getAppManager().addActivity(this); } public void btn(View view) {
// 除零错误,程序会崩溃
int c = 1 / 0;
} }
在这段代码里面,我们有益写了一个会出现异常的操作,除零。因此仅仅要点击button。程序就会崩溃。
以下,我们要自己实现接口。这里,我继承了Exception类。
package com.example.exceptiondemo; import java.lang.Thread.UncaughtExceptionHandler; import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Looper;
import android.widget.Toast; /**
*
* @ClassName: com.example.exceptiondemo.AppException
* @Description: 应用程序异常类:用于捕获异常
* @author zhaokaiqiang
* @date 2014-11-2 下午10:06:49
*
*/ public class AppException extends Exception implements UncaughtExceptionHandler { private static final long serialVersionUID = -6262909398048670705L; private String message; private Thread.UncaughtExceptionHandler mDefaultHandler; private AppException() {
super();
this.mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
} public AppException(String message, Exception excp) {
super(message, excp);
this.mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
} public String getMessage() {
return message;
} public void setMessage(String message) {
this.message = message;
} /**
* 获取APP异常崩溃处理对象
*
* @param context
* @return
*/
public static AppException getAppExceptionHandler() {
return new AppException();
} @Override
public void uncaughtException(Thread thread, Throwable ex) { if (!handleException(ex) && mDefaultHandler != null) {
mDefaultHandler.uncaughtException(thread, ex);
} } /**
* 自己定义异常处理
*
* @param ex
* @return true:处理了该异常信息;否则返回false
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return false;
} final Activity activity = AppManager.getAppManager().currentActivity(); if (activity == null) {
return false;
} new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(activity, "程序要崩了", Toast.LENGTH_SHORT).show();
new AlertDialog.Builder(activity).setTitle("提示")
.setCancelable(false).setMessage("亲。程序立即崩溃了...")
.setNeutralButton("没关系", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
AppManager.getAppManager().exitApp(activity);
}
}).create().show();
Looper.loop();
}
}.start(); return true;
} }
实现借口之后。我们须要在uncaughtException()方法里面处理自己的逻辑,我在这里面弹出对话框提示用户程序崩溃,这样。就比較友好一些。在代码里面的AppManager类是一个Activity的管理类。以下是代码
package com.example.exceptiondemo; import java.util.Stack; import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context; /**
*
* @ClassName: net.oschina.app.AppManager
* @Description: Activity管理类:用于管理Activity和退出程序
* @author zhaokaiqiang
* @date 2014-11-2 上午11:27:55
*
*/
public class AppManager { private static Stack<Activity> activityStack;
private static AppManager instance; private AppManager() {
} /**
* 单一实例
*/
public static AppManager getAppManager() {
if (instance == null) {
instance = new AppManager();
}
return instance;
} /**
* 加入Activity到堆栈
*/
public void addActivity(Activity activity) {
if (activityStack == null) {
activityStack = new Stack<Activity>();
}
activityStack.add(activity);
} /**
* 获取当前Activity(堆栈中最后一个压入的)
*/
public Activity currentActivity() {
Activity activity = activityStack.lastElement();
return activity;
} /**
* 结束当前Activity(堆栈中最后一个压入的)
*/
public void finishActivity() {
Activity activity = activityStack.lastElement();
finishActivity(activity);
} /**
* 结束指定的Activity
*/
public void finishActivity(Activity activity) {
if (activity != null) {
activityStack.remove(activity);
activity.finish();
activity = null;
}
} /**
* 结束指定类名的Activity
*/
public void finishActivity(Class<?> cls) {
for (Activity activity : activityStack) {
if (activity.getClass().equals(cls)) {
finishActivity(activity);
}
}
} /**
* 结束全部Activity
*/
public void finishAllActivity() {
for (int i = 0, size = activityStack.size(); i < size; i++) {
if (null != activityStack.get(i)) {
activityStack.get(i).finish();
}
}
activityStack.clear();
} /**
* 退出应用程序
*/
public void exitApp(Context context) {
try {
finishAllActivity();
ActivityManager activityMgr = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
activityMgr.killBackgroundProcesses(context.getPackageName());
System.exit(0);
} catch (Exception e) {
}
}
}
【Android开发经验】我们要友好的告诉用户,程序要崩溃了的更多相关文章
- ArcGIS for Android 10.1.1API 中文标注导致程序异常崩溃问题
1.前言 问题:在部分Android机型中使用ArcGIS for Android 10.1.1 API 中文标注导致程序异常崩溃. 说明:手里有两台机器一台是Nexus4,原生系统,版本4.4.4, ...
- Android开发经验02:Android 项目开发流程
Android开发完整流程: 一.用户需求分析 用户需求分析占据整个APP开发流程中最重要的一个环节.一款APP开发的成功与否很大程度都决定于此.这里所说的用户需求分析指的是基于用户的要求所进行的 ...
- Android Studio安装、配置、第一个程序的那些坑
最近在上Android课,老师布置了量大题难的作业,然而出师未捷身先死,还没看题目,就被Android Studio的安装和环境配置搞得要死要死的,网上的教程也多也杂,良莠不齐,在经历了5小时通过的搜 ...
- android上instant app介绍 类似于微信小程序
android上instant app介绍 类似于微信小程序instant app 是谷歌推出的类似于微信小程序(或者说小程序类似于instant app)的一项技术,用户无须安装应用,用完就走,同时 ...
- 第三部分:Android 应用程序接口指南---第三节:应用程序资源---第一章 资源提供
第1章 资源提供 你应该经常外部化你应用程序代码中的资源,比如图片.字符串等,这样有利于你独立处理这些资源.你也应该根据特定的设备配置提供一些可替代的资源,并且把他们分组保存在指定的路径名下.运行时, ...
- Android将应用程序的崩溃信息如何保存到本地文件,并上传服务器
导语:最近实在是太忙了,没有怎么更新公众号,也没有怎么认真去写一些内容,在这里先给关注我的朋友说一声抱歉,可能在接下来的一段时间,还是很忙,但是我会争取抽空多分享一下技术文章,给大家看,共同进步,也希 ...
- Android和java平台 DES加密解密互通程序及其不能互通的原因
网上的demo一搜一大堆,但是,基本上都是一知半解(包括我).为什么呢?我在尝试分别在两个平台加密的时候,竟然发现Android DES 加密和java DES加密的程序不能互通.就是加密的结果不一样 ...
- wemall doraemon中Android app商城系统工具集合类,包含各种程序中用到的静态方法
wemall doraemon中Android app商城系统工具集合类,包含各种程序中用到的静态方法,可用于其他商城或者系统的编程参考 package cn.zzu.edu.wemall.utils ...
- Android开发艺术探索——新的征程,程序人生路漫漫!
Android开发艺术探索--新的征程,程序人生路漫漫! 偶尔写点东西分享,但是我还是比较喜欢写笔记,看书,群英传看完了,是学到了点东西,开始看这本更加深入Android的书籍了,不知道适不适合自己, ...
随机推荐
- BZOJ3105: [cqoi2013]新Nim游戏(Xor线性无关组)
Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴 ...
- Tensorflow 学习笔记 -----tf.where
TensorFlow函数:tf.where 在之前版本对应函数tf.select 官方解释: tf.where(input, name=None)` Returns locations of true ...
- CentOS 7上安装gitlab-runner
1.yum install gitlab-runner -y 2.Registering Runners a.Run the following command: gitlab-runner regi ...
- 洛谷 P1683 入门
P1683 入门 题目描述 不是任何人都可以进入桃花岛的,黄药师最讨厌象郭靖一样呆头呆脑的人.所以,他在桃花岛的唯一入口处修了一条小路,这条小路全部用正方形瓷砖铺设而成.有的瓷砖可以踩,我们认为是安全 ...
- MongoDB + node-mongoskin简单演示样例
特点 无模式 MongoDB 中的每一条文档,都是一个 JSON 对象,因此你无需提前定义一个集合的结构,集合中的每一个文档也能够有不同的结构. 异步写入 MongoDB 默认全部的写操作都是『不安全 ...
- 1.6 INSERT语句
1.6 INSERT语句正在更新内容,请稍后
- Split Shape by Plane in OpenCASCADE
Split Shape by Plane in OpenCASCADE eryar@163.com Abstract. Sometimes you want to split a shape by p ...
- 【基础篇】点击Button按钮更换图片
我们在开发的过程中,往往为了美化界面的需要,会修改按钮的默认外观,而因为Android中的按钮有三种状态—默认,被点击,被选中.所以,如果要改变按钮的外观,需要对这三种情况都做出修改,也许在以往,我们 ...
- Stacked Autoencoders
转自:http://www.cnblogs.com/tornadomeet/archive/2013/03/25/2980357.html 如果使用多层神经网络的话,那么将可以得到对输入更复杂的函数表 ...
- Mysql学习总结(13)——使用JDBC处理MySQL大数据
一.基本概念 大数据也称之为LOB(Large Objects),LOB又分为:clob和blob,clob用于存储大文本,blob用于存储二进制数据,例如图像.声音.二进制文等. 在实际开发中,有时 ...