[已解决]项目中应用来回切换后,就会提示“已停止运行”

2023-10-12 13:58

本文主要是介绍[已解决]项目中应用来回切换后,就会提示“已停止运行”,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

经过debug,我发现是应用在调用我们的一个全局变量的时候,这个全局变量为空了,但是我们明明是有设置,而且在不切换之前也是有值的

原因分析:

最后在网上查找了一下,原来在内存较少的时候,来回切换的时候gc 会去将一些内存释放掉的,全局变量会被重新设置为默认值


模拟的方法:

1: 首先声明一个静态的全局变量类:

package com.example.kodulf.crashdemo;/*** Created by Kodulf on 2017/5/12.*/public class StaticClass {public static String staticString;public static int[] intArray;
}

2: 创建一个MainActivity

package com.example.kodulf.crashdemo;import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);StaticClass.staticString = "hello";//初始化静态类里面的数组,给一个很大的内存亮StaticClass.intArray = new int[1024*1024*25];//启动第二个ActivityIntent intent = new Intent(this,SecondActivity.class);startActivity(intent);}
}

3: 创建SecondActivity

package com.example.kodulf.crashdemo;import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;public class SecondActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_second);Log.d("kodulf",""+StaticClass.staticString);//下面这里// 在当前显示的是SecondActivity的时候切换到后台,然后再切换回来,在内存较少的情况下,会报错// 在当前显示的是SecondActivity的时候切换到后台,还有一种让他直接报错的方法,就是通过一些内存管理软件,在当前显示的是SecondActivity的时候切换到后台,点击内存清理,然后再切换回来 就会报错了Log.d("kodulf",""+StaticClass.intArray.length);}}


4: 最直接的模拟方法:

启动该应用,默认的会在MainActivity的时候初始化那个静态的int数组,然后会自动启动SecondActivity

这个时候将该应用切换到后台

找到一个内存管理的工具,例如360软件助手,进行内存清理,

再将该应用切换回来,就会直接报错了



解决办法:

将全局变量尽量使用常量,如果要涉及到修改的全局变量,那么最好不要直接食用

1: 可以使用sharepreference 去保存然后。

2: 或者在onSaveInstanceState的时候保存这个全局变量,onRestoreInstanceState 的时候再给这个全局变量重新赋值就好了。

package com.example.kodulf.crashdemo;import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;public class SecondActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_second);Log.d("kodulf",""+StaticClass.staticString);//下面这里// 在当前显示的是SecondActivity的时候切换到后台,然后再切换回来,在内存较少的情况下,会报错// 在当前显示的是SecondActivity的时候切换到后台,还有一种让他直接报错的方法,就是通过一些内存管理软件,在当前显示的是SecondActivity的时候切换到后台,点击内存清理,然后再切换回来 就会报错了Log.d("kodulf",""+StaticClass.intArray.length);}@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);outState.putSerializable("intArray",StaticClass.intArray);}@Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState) {super.onRestoreInstanceState(savedInstanceState);StaticClass.intArray = (int[])savedInstanceState.getSerializable("intArray");}
}




+++++++++++++++++++++++++++++++++++++++++

参考:http://blog.csdn.net/hs_73/article/details/50911133

后期测试的时候,发现有个偶然现象,当应用被切换到后台一段时间再切换回来的时候会莫名的崩溃,而且在log的错误信息,云测以及友盟的错误列表上都没有发现有错误日志输出。确实是比较棘手,但这确实是应用的bug,无法忽视,但是这个问题又无法很容易的重现。后期查找资料分析一下,可能是跟这几个原因有关:

1.没有很正确的理解getContext() , getActivity() ,Activity.this ,getApplicationContext的区别以及用法,乱用导致:

Context:上下文(指的就是这个应用运行所依赖的运行环境), Context分类:
       ①.Activity:具体的上下文环境;Activity.this的context属于activity ,activity 摧毁他就摧毁
       ②.ApplicationContext:整体的上下文环境;getApplicationContext()通过该方法获取,getApplicationContext() 生命周期是整个应用,应用摧毁它才摧毁 
       ③getContext();. getContext获取的是当前对象所在的Context
对于绝大多数场景,使用Activity或者是ApplicationContext效果都一样.
activity.this要返回一个activity,而getApplicationContext()就不一定返回一个activity
      但是有些特殊情况下,使用Activity这种上下文的地方,不可以使用ApplicationContext;
      也有些地方,使用ApplicationContext的地方,也不能使用Activity:一般是需要对全局做初始化操作的时候.

 2.应用被切换到后台以后,由于Android的内存回收机制,Activity切换到后台之后,由于内存不够,此Activity被系统回收了,一段时间之后回到该应用程序,Activity被重新实例化了。而Activity被系统销毁时,附属在该Activity的Fragment并没有被销毁,在Activity的onSaveInstanceState里面将Fragment状态保存起来了,所以Activity重新创建了,但是FragmentA和FragmentB还是之前的,而此时FragmentA和FragmentB所附属的Activity已经被系统回收了,这次再调用getActivity时返回了null,我们看看FragmentActivity源码中的onSaveInstanceState方法:

[java]  view plain copy
  1. protected void onSaveInstanceState(Bundle outState)  
  2.    {  
  3.      super.onSaveInstanceState(outState);  
  4.      Parcelable p = mFragments.saveAllState();  
  5.      if (p != null) {  
  6.        outState.putParcelable("android:support:fragments", p);  
  7.     }  
  8.    }  
由上面源码可以看出,FragmentActivity确实在onSaveInstanceState方法里面将Fragment的状态保存了。 解决方法其实很简单,我们只要让FragmentActivity被系统回收的时候,不保存Fragment的状态即可,即在FragmentActivity中重写onSaveInstanceState方法,并且注释掉super.onSaveInstanceState(outState)就行了。
[java]  view plain copy
  1. @Override  
  2.  protected void onSaveInstanceState(Bundle outState) {  
  3. //        super.onSaveInstanceState(outState);  
  4. }  

参考:http://www.cnblogs.com/liuling/p/2015-9-21-1.html

3.存在某些全局静态变量被释放回收掉,再次打开时,由于缺少值,在一些配置较低的终端上容易出现。

4.还比如,从一个界面跳转到第二个界面时,存在传值,当在第二个界面时应用被切换到后台,当你再切换到前台时,在这第二个activity里,在其onResume()方法中做了数据访问用到了前一个界面的传值,当这个值已经被回收掉,这时就会crash掉了,多做些非空判断总归是有利无弊的。

造成这个问题的原因可能很多,以上是我个人的项目经验,仅代表个人观点,欢迎补充指正。




这篇关于[已解决]项目中应用来回切换后,就会提示“已停止运行”的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/196313

相关文章

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

Python中re模块结合正则表达式的实际应用案例

《Python中re模块结合正则表达式的实际应用案例》Python中的re模块是用于处理正则表达式的强大工具,正则表达式是一种用来匹配字符串的模式,它可以在文本中搜索和匹配特定的字符串模式,这篇文章主... 目录前言re模块常用函数一、查看文本中是否包含 A 或 B 字符串二、替换多个关键词为统一格式三、提

Redis出现中文乱码的问题及解决

《Redis出现中文乱码的问题及解决》:本文主要介绍Redis出现中文乱码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 问题的产生2China编程. 问题的解决redihttp://www.chinasem.cns数据进制问题的解决中文乱码问题解决总结

Java MQTT实战应用

《JavaMQTT实战应用》本文详解MQTT协议,涵盖其发布/订阅机制、低功耗高效特性、三种服务质量等级(QoS0/1/2),以及客户端、代理、主题的核心概念,最后提供Linux部署教程、Sprin... 目录一、MQTT协议二、MQTT优点三、三种服务质量等级四、客户端、代理、主题1. 客户端(Clien

如何在Spring Boot项目中集成MQTT协议

《如何在SpringBoot项目中集成MQTT协议》本文介绍在SpringBoot中集成MQTT的步骤,包括安装Broker、添加EclipsePaho依赖、配置连接参数、实现消息发布订阅、测试接口... 目录1. 准备工作2. 引入依赖3. 配置MQTT连接4. 创建MQTT配置类5. 实现消息发布与订阅

springboot项目打jar制作成镜像并指定配置文件位置方式

《springboot项目打jar制作成镜像并指定配置文件位置方式》:本文主要介绍springboot项目打jar制作成镜像并指定配置文件位置方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录一、上传jar到服务器二、编写dockerfile三、新建对应配置文件所存放的数据卷目录四、将配置文

Python中Tensorflow无法调用GPU问题的解决方法

《Python中Tensorflow无法调用GPU问题的解决方法》文章详解如何解决TensorFlow在Windows无法识别GPU的问题,需降级至2.10版本,安装匹配CUDA11.2和cuDNN... 当用以下代码查看GPU数量时,gpuspython返回的是一个空列表,说明tensorflow没有找到

解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题

《解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题》:本文主要介绍解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4... 目录未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘打开pom.XM

XML重复查询一条Sql语句的解决方法

《XML重复查询一条Sql语句的解决方法》文章分析了XML重复查询与日志失效问题,指出因DTO缺少@Data注解导致日志无法格式化、空指针风险及参数穿透,进而引发性能灾难,解决方案为在Controll... 目录一、核心问题:从SQL重复执行到日志失效二、根因剖析:DTO断裂引发的级联故障三、解决方案:修复

IDEA Maven提示:未解析的依赖项的问题及解决

《IDEAMaven提示:未解析的依赖项的问题及解决》:本文主要介绍IDEAMaven提示:未解析的依赖项的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录IDEA Maven提示:未解析的依编程赖项例如总结IDEA Maven提示:未解析的依赖项例如