【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的书籍了,不知道适不适合自己, ...
随机推荐
- angular4自定义组件非input元素实现ngModel双向数据绑定
在angular里我们一般都是给input元素添加[(ngModel)]="value"实现数据双向绑定,如果想实现自定义的组件上实现ngModel双向数据绑定应该怎么办呐... ...
- 学习参考《零基础入门学习Python》电子书PDF+笔记+课后题及答案
国内编写的关于python入门的书,初学者可以看看. 参考: <零基础入门学习Python>电子书PDF+笔记+课后题及答案 Python3入门必备; 小甲鱼手把手教授Python; 包含 ...
- PHP CURL HTTPS POST
PHP CURL HTTPS POST function vpost($url,$data){ // 模拟提交数据函数 $curl = curl_init(); // 启动一个CURL会话 ...
- SFML学习纪要
工作需要,近段粗浅看了一下SFML,记录一下! 一.浅见概述 SFML,simple and Fast mulitmedia Library官方网站:http://www.sfml-dev.org/i ...
- Swift学习笔记(3)--基本运算符
基本运行符: +(加法.正数) - (减法.负数) * (乘法) / (除法) % (求余) : 在Swift中,求余可以是浮点数求余. &&(逻辑与) || (逻辑或) ^ (逻 ...
- 【转】Flash AS3.0 中的自定义事件
原文 http://www.cnblogs.com/acpp/archive/2010/10/19/1855670.html package { import flash.events.Event; ...
- Activiti工作流(3):activiti核心API
ProcessEngine 说明: 1) 在Activiti中最核心的类,其他的类都是由他而来. 2) 产生方式:ProcessEngine defaultProcessEngine = Pr ...
- Objective-C method及相关方法分析
## Objective-C method及相关方法分析 转载请注名出处 [http://blog.csdn.net/uxyheaven](http://blog.csdn.net/uxyheaven ...
- 洛谷P1720 月落乌啼算钱
目背景 (本道题目木有以藏歌曲……不用猜了……) <爱与愁的故事第一弹·heartache>最终章. 吃完pizza,月落乌啼知道超出自己的预算了.为了不在爱与愁大神面前献丑,只好还是硬着 ...
- GridView1.DataKeys[e.RowIndex].Value 是什么含义?
https://zhidao.baidu.com/question/88518619.html举个例子来说吧 你将一个student表绑定到grid上 这个表里有一些字段 包括id 姓名 学号 等等等 ...