关于安卓应用后台运行后,重新进入,应用闪退问题

简介: 安卓应用后台运行后,重新进入,应用闪退问题

       现象:安卓应用后台运行后,在系统内存紧张下,应用会被kill掉,当用户点击应用图标重新进入的时候,就会闪退,大部分报错信息,都是空指针的错误。

       为什么会造成这种情况?首先,应用进程被kill掉(application被Kill,相关变量被清空),这个是可以确定的,但是,正常情况下(魔改过的rom不纳入考虑范围),应用的任务栈没有被清空,系统还是保留了原来应用的任务栈,当用户重新进入activity的时候,当用到某些已经被清空的变量时,就会NullPointerException报错。

       下面先说一下安卓activity的启动模式,分别为:Standard,SingleTop,SingleTask,SingleInstance。

       Standard:标准模式。默认的activity启动模式,也是我们最常用的模式。该模式下,activity启动会生成一个实例,然后进入我们调用的任务栈,假如原本的任务栈是:A-B-C,且当前显示的是C Activity,那么,C启动D,就会变成A-B-C-D,且D显示,D启动D,就会变成A-B-C-D-D,D显示,以上为Activity调用的情况。对于Application调用,需要加上new task标识,细心的读者,此时发现,生成的Activity是以singletask模式启动的。

       SingleTop:单一顶部模式,使用该模式的Activity,在启动的时候,会检查启动栈内的栈顶是否已经存在实例,若存在,则不会新建一个实例,会执行onNewIntent函数,注意onCreate(),onStart()方法不会执行。否则创建一个新的实例并入栈。例子:(1)当前任务栈为A-B-C,A为SingleTop模式,这个时候,C启动A,任务栈会变成A-B-C-A。(2)当前任务栈为A-B-C-A,A为SingleTop模式,这个时候,A启动A,任务栈还是A-B-C-A。

       SingleTask:栈内复用模式,使用该模式的Activity,在启动的时候,会检查启动栈内的栈顶是否已经存在实例,若存在,则不会新建一个实例,会清空其栈以上的Activity,使其成为栈顶Activity。并执行onNewIntent函数。若不存在,则新建一个任务栈,并且把Activity放入该任务栈中。

       SingleInstance:单实例模式,具有SingleTask的所有属性,并且启动该模式的Activity时,该Activity只能单独存在一个任务栈中。加入B启动了具有SingleInstance特性的A Activity,系统就会创建一个新的任务栈,并把A放入,后续启动A,都不会创建A的实例,除非A所在的任务栈被销毁。


       本次实战,MainActivity的启动模式为SingleTask,其余Activity的启动模式均为Standard。

       首先我们需要模拟应用进入后台,并且被系统Kill的情况。(这个有多种方法实现,作者使用的是手机开发者模式里面的不允许后台任务模式)

       情况1:应用打开了首页,退回后台,被系统kill后,重新进入应用,应用闪退,报空指针错。

       情况2:应用打开了二级页面,退回后台,被系统kill后,重新进入应用,应用闪退,同样报空指针错。

       思考:空指针报错,就是之前提及的系统Kill应用后,变量被释放造成的。那么我们如何处理?首先,被kill后的应用,用户再次点击进入,应用就会根据旧的任务栈信息进行复原Activity。由于Activity已经被销毁,所以Activity需要走重新创建的流程,重点就是,某些变量值,已经被释放了,这个时候,我选择的方法,就是在Activity的onCreate()方法里面,进行判断,如果是已经被销毁后,重新创建的Activity,这种情况下,我们直接启动MainActivity,然后在MainActivity的onNewInstance()方法里面判断,最后确定是否需要重新启动应用。

       再次提醒,上述使用情况,MainActivity的启动模式为SingleTask,其余Activity的启动模式均为Standard。其余的情况,其实也是大同小异,需要注意的是,各个Activity的启动模式,然后在对应的函数里面进行判断。

       返回代码,首先,我们定义一个类,用来记录Activity的启动:


网络异常,图片无法展示
|

启动标识记录类

网络异常,图片无法展示
|

启动标识判断类

当我们应用启动的时候,或者是在欢迎页面的时候,通过调用AppStatusManager,把mAppStatus的值设置为AppStatus类里面的正常态,如下图:


网络异常,图片无法展示
|

设置正常态

然后,在Activity的基类里面,onCreate方法中,加一个是否被后台Kill的判断(对于后台kill,变量值都会恢复到默认值),若是,则打开MainActivity,否则正常启动。(有人会问,为什么要打开MainActivity,而不是直接重启应用,这个是因为SingleTask的特别性,所以要特别处理)BaseActivity的onCreate处理逻辑如下图:


网络异常,图片无法展示
|

BaseActivity onCreate方法处理

走完上述的步骤,由于SingleTask的特别性,所以任务栈里面就剩一个MainActivity了。这个时候,我们要着手处理MainActivity的函数onNewIntent(),如下图:


网络异常,图片无法展示
|

MainActivity onNewIntent

这个情况进入,我建议是app进行finish掉MainActivity后,重启走一次启动流程的,这样更加符合规范。所以这里直接启动了欢迎页面,然后finish当前的MainActivity了。


至此,问题修复完成,若有不正之处,请指出,定更正。

目录
相关文章
|
10天前
|
IDE Java 开发工具
深入探索安卓应用开发:从环境搭建到第一个"Hello, World!"应用
本文将引导读者完成安卓应用开发的初步入门,包括安装必要的开发工具、配置开发环境、创建第一个简单的安卓项目,以及解释其背后的一些基本概念。通过一步步的指导和解释,本文旨在为安卓开发新手提供一个清晰、易懂的起点,帮助读者顺利地迈出安卓开发的第一步。
189 65
|
10天前
|
存储 Java Android开发
探索安卓应用开发:构建你的第一个"Hello World"应用
【9月更文挑战第24天】在本文中,我们将踏上一段激动人心的旅程,深入安卓应用开发的奥秘。通过一个简单而经典的“Hello World”项目,我们将解锁安卓应用开发的基础概念和步骤。无论你是编程新手还是希望扩展技能的老手,这篇文章都将为你提供一次实操体验。从搭建开发环境到运行你的应用,每一步都清晰易懂,确保你能顺利地迈出安卓开发的第一步。让我们开始吧,探索如何将一行简单的代码转变为一个功能齐全的安卓应用!
|
15天前
|
开发框架 搜索推荐 开发工具
打造个性化安卓应用:从零开始的Flutter之旅
【8月更文挑战第51天】本文是一篇面向初学者的Flutter入门教程,旨在通过简单易懂的语言和实际代码示例,引导读者步入跨平台移动应用开发的世界。文章首先介绍了Flutter的基本概念和优势,然后逐步展示了如何搭建开发环境、创建第一个Flutter应用,并实现了一个简单的待办事项列表。最后,文章探讨了Flutter在实现高性能和美观界面方面的潜力,鼓励读者发挥创意,探索更多可能。
65 15
|
5天前
|
监控 安全 Java
Kotlin 在公司上网监控中的安卓开发应用
在数字化办公环境中,公司对员工上网行为的监控日益重要。Kotlin 作为一种基于 JVM 的编程语言,具备简洁、安全、高效的特性,已成为安卓开发的首选语言之一。通过网络请求拦截,Kotlin 可实现网址监控、访问时间记录等功能,满足公司上网监控需求。其简洁性有助于快速构建强大的监控应用,并便于后续维护与扩展。因此,Kotlin 在安卓上网监控应用开发中展现出广阔前景。
9 1
|
19天前
|
搜索推荐 Java Android开发
打造个性化安卓应用:从设计到发布的全程指南
【9月更文挑战第15天】本篇文章将带领读者踏上一段激动人心的旅程,从构思一个独特的安卓应用想法开始,直至将其变为现实并成功发布。我们将一起探索如何捕捉灵感、设计界面、编写代码以及最终将应用推向市场。无论你是编程新手还是有经验的开发者,这篇文章都将为你提供宝贵的洞见和实用的技巧,让你的应用在竞争激烈的市场中脱颖而出。
56 17
|
15天前
|
Java Android开发 UED
🧠Android多线程与异步编程实战!告别卡顿,让应用响应如丝般顺滑!🧵
在Android开发中,为应对复杂应用场景和繁重计算任务,多线程与异步编程成为保证UI流畅性的关键。本文将介绍Android中的多线程基础,包括Thread、Handler、Looper、AsyncTask及ExecutorService等,并通过示例代码展示其实用性。AsyncTask适用于简单后台操作,而ExecutorService则能更好地管理复杂并发任务。合理运用这些技术,可显著提升应用性能和用户体验,避免内存泄漏和线程安全问题,确保UI更新顺畅。
38 5
|
16天前
|
前端开发 Java 数据库
💡Android开发者必看!掌握这5大框架,轻松打造爆款应用不是梦!🏆
在Android开发领域,框架犹如指路明灯,助力开发者加速应用开发并提升品质。本文将介绍五大必备框架:Retrofit简化网络请求,Room优化数据库访问,MVVM架构提高代码可维护性,Dagger 2管理依赖注入,Jetpack Compose革新UI开发。掌握这些框架,助你在竞争激烈的市场中脱颖而出,打造爆款应用。
86 3
|
16天前
|
存储 API Android开发
"解锁Android权限迷宫:一场惊心动魄的动态权限请求之旅,让你的应用从平凡跃升至用户心尖的宠儿!"
随着Android系统的更新,权限管理成为应用开发的关键。尤其在Android 6.0(API 级别 23)后,动态权限请求机制的引入提升了用户隐私保护,要求开发者进行更精细的权限管理。
43 2
|
24天前
|
开发框架 Android开发 iOS开发
探索安卓与iOS开发的差异:构建未来应用的指南
在移动应用开发的广阔天地中,安卓与iOS两大平台各占半壁江山。本文将深入浅出地对比这两大操作系统的开发环境、工具和用户体验设计,揭示它们在编程语言、开发工具以及市场定位上的根本差异。我们将从开发者的视角出发,逐步剖析如何根据项目需求和目标受众选择适合的平台,同时探讨跨平台开发框架的利与弊,为那些立志于打造下一个热门应用的开发者提供一份实用的指南。
51 5
|
22天前
|
Android开发 开发者 Kotlin
告别AsyncTask:一招教你用Kotlin协程重构Android应用,流畅度飙升的秘密武器
【9月更文挑战第13天】随着Android应用复杂度的增加,有效管理异步任务成为关键。Kotlin协程提供了一种优雅的并发操作处理方式,使异步编程更简单直观。本文通过具体示例介绍如何使用Kotlin协程优化Android应用性能,包括网络数据加载和UI更新。首先需在`build.gradle`中添加coroutines依赖。接着,通过定义挂起函数执行网络请求,并在`ViewModel`中使用`viewModelScope`启动协程,结合`Dispatchers.Main`更新UI,避免内存泄漏。使用协程不仅简化代码,还提升了程序健壮性。
45 1
下一篇
无影云桌面