我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android怎样实现友好崩溃界面

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android怎样实现友好崩溃界面

Android怎样实现友好崩溃界面,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

Android 的默认崩溃机制是 APP 闪退,然后显示一个【xxx 已停止运行】的对话框或 Toast,而崩溃的详情只有开发者在 Logcat 里才能看到,用户看到发生了这样的情况肯定一头雾水,的确,这样默认的异常处理方式很不友好,容易造成用户流失。我们现在要做的是,程序发生异常时,新开一个 Activity 向用户致歉,输出详细的异常信息,并提供将异常信息提交给开发者的功能。

首先,在 BaseActivity 里封装方法:

public abstract class BaseActivity extends AppCompatActivity {    private static final AppManager MANAGER = AppManager.get();         @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        MANAGER.addActivity(this);    } // onCreate()         @Override    protected void onDestroy() {        super.onDestroy();        MANAGER.removeActivity(this);    } // onDestroy()         protected void crash(Exception e) {        Intent i;        String dump;        PrintWriter pw;        StringWriter sw;         sw = new StringWriter();        pw = new PrintWriter(sw);        e.printStackTrace(pw);        pw.flush();        dump = sw.toString();        i = new Intent(this, CrashActivity.class);        i.putExtra("dump", dump);        startActivity(i);        MANAGER.finishAllExcept(CrashActivity.class);    } // crash()         String getCrashDump() {        return getIntent().getStringExtra("dump");    } // getCrashDump()} // BaseActivity Abstract Class // E.O.F

BaseActivity 里用到了两个自定义类,AppManager 和 CrashActivity。后面添加的这两个类请确保和 BaseActivity 在同一包下。

添加 AppManager 类:

class AppManager {    private static final AppManager MANAGER = new AppManager();    private Stack<BaseActivity> mStack;     private AppManager() {        // 将作用域关键字设置为 private 以隐藏该类的构造器。        mStack = new Stack<>();    } // AppManager() (Class Constructor)         static AppManager get() {        return MANAGER;    } // get()         void addActivity(BaseActivity activity) {        mStack.add(activity);        Log.i("AppManager", "[+] Created: " + activity.getClass().getName());    } // addActivity()         void removeActivity(BaseActivity activity) {        mStack.remove(activity);        Log.i("AppManager", "<-> Removed: " + activity.getClass().getName());    } // removeActivity()         void finishAllExcept(Class<?> cls) {        int i, len;        BaseActivity[] activities;         // 结束活动时会调用活动的 onDestroy() 方法,堆栈的内容会实时改变        // 为避免因此引起的引用错误,先将堆栈的内容复制到一个临时数组里        activities = mStack.toArray(new BaseActivity[0]);        len = activities.length;        for (i = 0; i < len; ++i) {            if (activities[i].getClass() != cls) {                // 从数组里引用活动对象并结束,堆栈内容的改变不影响数组                activities[i].finish();            } // if (activities[i].getClass() != cls)        } // for (i = 0; i < len; ++i)    } // finishAllExcept()         void finishAllActivities() {        int i, len;        BaseActivity[] activities;         // 结束活动时会调用活动的 onDestroy() 方法,堆栈的内容会实时改变        // 为避免因此引起的引用错误,先将堆栈的内容复制到一个临时数组里        activities = mStack.toArray(new BaseActivity[0]);        len = activities.length;        for (i = 0; i < len; ++i) {            // 从数组里引用活动对象并结束,堆栈内容的改变不影响数组            activities[i].finish();        } // for (i = 0; i < len; ++i)    } // finishAllActivities()} // AppManager Class // E.O.F

新建 CrashActivity 活动。

活动的布局文件 activity_crash.xml

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#1A237E"    tools:context=".base.CrashActivity">    <!-- 请自行设置 background 和 textColor -->     <TextView        android:id="@+id/lblCrashMsg"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginStart="8dp"        android:layout_marginLeft="8dp"        android:layout_marginTop="8dp"        android:layout_marginEnd="8dp"        android:layout_marginRight="8dp"        android:layout_marginBottom="8dp"        android:gravity="center"        android:text="@string/lblCrashMsg"        android:textAppearance="?android:attr/textAppearanceMedium"        android:textColor="#EEEEEE"        app:layout_constraintBottom_toTopOf="@+id/lblCrashDetail"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toTopOf="parent" />     <TextView        android:id="@+id/lblCrashDetail"        android:layout_width="0dp"        android:layout_height="0dp"        android:layout_marginStart="8dp"        android:layout_marginLeft="8dp"        android:layout_marginTop="8dp"        android:layout_marginEnd="8dp"        android:layout_marginRight="8dp"        android:layout_marginBottom="8dp"        android:textColor="#EEEEEE"        android:typeface="monospace"        app:layout_constraintBottom_toBottomOf="parent"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toBottomOf="@+id/lblCrashMsg" /></android.support.constraint.ConstraintLayout>

字符串资源 strings.xml 里添加

<string name="lblCrashMsg">    程序发生了非预期错误    \n非常抱歉给您造成不便    \n以下是错误详情</string>

CrashActivity.java 代码:

public class CrashActivity extends BaseActivity { // 注意此处是继承 BaseActivity        @Override    protected void onCreate(Bundle savedInstanceState) {        String dump;        TextView lblDetail;         super.onCreate(savedInstanceState);        setContentView(R.layout.activity_crash);        dump = getCrashDump();        lblDetail = findViewById(R.id.lblCrashDetail);        lblDetail.setText(dump);        lblDetail.setMovementMethod(ScrollingMovementMethod.getInstance());    } // onCreate()         @Override    public boolean onKeyDown(int keyCode, KeyEvent event) {        if (keyCode == KeyEvent.KEYCODE_BACK) {            AppManager.get().finishAllActivities();            return true;        } // if (keyCode == KeyEvent.KEYCODE_BACK)        else {            return super.onKeyDown(keyCode, event);        } // else    } // onKeyDown()         @Override    protected void onUserLeaveHint() {        AppManager.get().finishAllActivities();    } // onUserLeaveHint()} // CrashActivity Class // E.O.F

下面我们要做的就是,在程序抛出异常时捕获它,并将异常内容带入 CrashActivity 中。要实现这样的操作,我们需要在 Activity 中的所有 public 和 protected 方法里添加 try/catch 语句块。(private 方法不用添加,因为 private 方法也必然是由某个 public 或 protected 方法调用的,而调用它的 public/protected 方法已经在抓捕异常了)

我们在 MainActivity 里添加一个按钮。activity_main.xml 布局代码如下:

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">     <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:onClick="onBtnCrashTestTapped"        android:text="@string/btnMainCrashTest"        app:layout_constraintBottom_toBottomOf="parent"        app:layout_constraintLeft_toLeftOf="parent"        app:layout_constraintRight_toRightOf="parent"        app:layout_constraintTop_toTopOf="parent" /></android.support.constraint.ConstraintLayout>

strings.xml 里添加:

<string name="btnMainCrashTest">崩溃测试</string>

MainActivity.java 代码:

public class MainActivity extends BaseActivity { // 注意此处是继承 BaseActivity    @Override    protected void onCreate(Bundle savedInstanceState) {        // protected 方法必须以 try/catch 包裹        // 在 catch 中加入 crash(e); 语句实现友好崩溃        try {            super.onCreate(savedInstanceState);            setContentView(R.layout.activity_main);        } // try        catch (Exception e) {            crash(e);        } // catch (Exception e)    } // onCreate()     public void onBtnCrashTestTapped(View v) {        int[] arr;         // public 方法必须以 try/catch 包裹        // 在 catch 中加入 crash(e); 语句实现友好崩溃        try {            arr = new int[4];            crashTest(arr);        } // try        catch (Exception e) {            crash(e);        } // catch (Exception e)    } // onBtnCrashTestTapped()     private void crashTest(int[] arr) {        // private 方法不用以 try/catch 包裹        // 除非调用了带 throws 关键字的方法强制要求捕获异常        arr[4] = 4; // 因为传入的 arr 数组长度为 4,所以此处会抛出数组越界异常    } // crashTest()} // MainActivity Class // E.O.F

安装到手机上测试一下

Android怎样实现友好崩溃界面

点击【崩溃测试】按钮

Android怎样实现友好崩溃界面

这里的演示程序并没有添加向开发者提交错误报告的功能,当然重点在于实现友好的崩溃界面。

看完上述内容,你们掌握Android怎样实现友好崩溃界面的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android怎样实现友好崩溃界面

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android怎样实现友好崩溃界面

Android怎样实现友好崩溃界面,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Android 的默认崩溃机制是 APP 闪退,然后显示一个【xxx 已停止运行】的对话框或 T
2023-06-21

php怎样实现加好友功能

这篇文章给大家分享的是有关php怎样实现加好友功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、把好友申请储存到申请数据表中。2、查询申请表。3、实现删除好友。4、创建分组名称字段。5、查询并列出数据表信息即
2023-06-25

android怎么实现界面滑动

在Android中,可以使用ScrollView、RecyclerView、ViewPager等控件来实现界面滑动。下面分别介绍这些控件的使用方法:1. ScrollView:ScrollView是一个可滚动的View容器,可以用于包裹一组
2023-08-18

Android怎么实现3D界面效果

要实现3D界面效果,可以通过以下几种方法:1. 使用OpenGL ES:Android支持OpenGL ES库,可以使用OpenGL ES来创建和渲染3D界面。通过使用OpenGL ES,可以定义3D模型、相机视角、光照和材质等元素,实现真
2023-08-24

怎样实现小程序的界面设计

小程序的界面设计通常需要遵循以下步骤来实现:确定设计风格:首先需要确定小程序的设计风格,包括颜色搭配、字体选择、图标样式等。可以根据小程序的定位和目标用户群来确定设计风格。设计原型:根据小程序的功能和需求,设计出界面的布局和交互流程。可以使
怎样实现小程序的界面设计
2024-04-17

Android studio怎么实现app登录界面

这篇文章主要介绍了Android studio怎么实现app登录界面的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android studio怎么实现app登录界面文章都会有所收获,下面我们一起来看看吧。And
2023-06-30

Android怎么实现设置界面横移

要在Android中实现设置界面的横向滑动,你可以使用ViewPager和TabLayout组合来实现。以下是实现的步骤:1. 在你的布局文件中,添加一个ViewPager和一个TabLayout,ViewPager用于显示不同的设置页面,
2023-10-18

Android Studio怎么实现登录界面功能

本文小编为大家详细介绍“Android Studio怎么实现登录界面功能”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android Studio怎么实现登录界面功能”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧
2023-06-30

Android怎么使用RecyclerView实现瀑布流界面

今天小编给大家分享一下Android怎么使用RecyclerView实现瀑布流界面的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下
2023-07-05

Android studio怎么实现两个界面间的切换

本文小编为大家详细介绍“Android studio怎么实现两个界面间的切换”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android studio怎么实现两个界面间的切换”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习
2023-06-30

Android怎么实现网易云推荐歌单界面

这篇文章主要介绍“Android怎么实现网易云推荐歌单界面”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Android怎么实现网易云推荐歌单界面”文章能帮助大家解决问题。一、实现1.自定义一个圆角图
2023-06-29

android怎么实现点击按钮跳转界面功能

在Android中,可以通过以下方式实现点击按钮跳转界面的功能:1. 在布局文件中添加一个按钮控件,例如:```xmlandroid:id="@+id/button"android:layout_width="wrap_content"an
2023-08-08

Android项目中怎么实现一个可拖拽界面

本篇文章为大家展示了Android项目中怎么实现一个可拖拽界面,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。以自定义ImageView为例:/** * 可拖拽ImageView * Created
2023-05-31

Android中怎么实现右滑返回上一个界面

今天就跟大家聊聊有关Android中怎么实现右滑返回上一个界面,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Android右滑返回上一个界面的实现方法public class Bas
2023-05-30

怎么在Android中使用Kotlin实现一个登录界面

怎么在Android中使用Kotlin实现一个登录界面?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。登录界面代码如下:class LoginActivity :
2023-05-30

Android中怎么实现仿iOS侧滑退出当前界面功能

小编给大家分享一下Android中怎么实现仿iOS侧滑退出当前界面功能,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!首先看下效果图:分析:(1)要想模仿ios的这
2023-05-30

Android中通过样式来去除app的头及界面全屏(备忘)的实现方法

在style中如下面那样定义: