Android 如何确保finish()销毁活动并清除所有变量?
我在一个有两个活动的项目中工作,一个显示数据库中的行列表,当您单击其中一个时,它会打开另一个活动,其中包含可以编辑的元素 问题是,当我关闭第二个活动并重新打开它时(即使我调用Android 如何确保finish()销毁活动并清除所有变量?,android,Android,我在一个有两个活动的项目中工作,一个显示数据库中的行列表,当您单击其中一个时,它会打开另一个活动,其中包含可以编辑的元素 问题是,当我关闭第二个活动并重新打开它时(即使我调用finish()),一些变量会保留上一次“会话”的数据 所以可能的问题是:如何清除所有变量/销毁活动 编辑 在我不断阅读和尝试的过程中,我仍然无法找出真正的问题所在,因此还有一些额外的信息: -我正在使用的自定义控制器 public class CustomEditText extends EditText { p
finish()
),一些变量会保留上一次“会话”的数据
所以可能的问题是:如何清除所有变量/销毁活动
编辑
在我不断阅读和尝试的过程中,我仍然无法找出真正的问题所在,因此还有一些额外的信息:
-我正在使用的自定义控制器
public class CustomEditText extends EditText {
private boolean edited=false;
private boolean init;
private boolean justLoad;
private String oldText;
public boolean required;
public boolean isEdited() {
return edited;
}
public String getOldText() {
return oldText;
}
public CustomEditText(Context context) {
super(context);
}
public CustomEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
super.onTextChanged(text, start, lengthBefore, lengthAfter);
if (justLoad) {
edited=false;
justLoad=false;
} else {
String currtext = this.getText().toString();
if (!init) {
oldText = currtext;
init = true;
}
if (!currtext.equals(oldText)) {
edited = true;
} else {
edited = false;
}
}
Log.d("cet",this.getText().toString()+" != "+oldText+" "+edited);
}
public void load(String text){
init=true;
oldText=text;
edited=false;
justLoad=true;
this.setText(text);
}
}
-实用程序类(也尝试非静态)
public class CustomViewUtilities {
private static boolean edited=false;
private static ArrayList<EditText> list = new ArrayList<>();
public static boolean isAnyEdited(ViewGroup view){
CustomViewUtilities c = new CustomViewUtilities();
c.traverseEditTexts(view);
return edited;
}
public static ArrayList<EditText> getList(ViewGroup view) {
list.clear();
CustomViewUtilities c = new CustomViewUtilities();
c.traverseEditTexts(view);
return list;
}
private EditText traverseEditTexts(ViewGroup v)
{
EditText invalid = null;
for (int i = 0; i < v.getChildCount(); i++)
{
Object child = v.getChildAt(i);
if (child instanceof EditText)
{
EditText e = (EditText)child;
if (e instanceof CustomAutoCompleteTextView){
list.add(e);
if (((CustomAutoCompleteTextView) e).isEdited()) {
edited = true;}
} else if (e instanceof CustomEditText) {
if (((CustomEditText) e).isEdited()) {
edited = true;}
list.add(e);
}
}
else if(child instanceof ViewGroup)
{
invalid = traverseEditTexts((ViewGroup)child); // Recursive call.
if(invalid != null)
{
break;
}
}
}
return invalid;
}
}
公共类CustomViewUtilities{
私有静态布尔编辑=false;
私有静态ArrayList=新ArrayList();
公共静态布尔值已编辑(视图组视图){
CustomViewUtilities c=新的CustomViewUtilities();
c、 traverseEditTexts(视图);
返回编辑;
}
公共静态ArrayList getList(视图组视图){
list.clear();
CustomViewUtilities c=新的CustomViewUtilities();
c、 traverseEditTexts(视图);
退货清单;
}
私有EditText遍历EditTexts(视图组v)
{
EditText无效=空;
对于(int i=0;i
我还试图更改android:launchMode,但没有结果。
问题在于,如果CustomViewUtilities.isAnyEdited(view);
方法在下次启动活动时返回true,则在我第二次启动活动时,该方法将返回true
非常感谢您的帮助。如果您保留活动中的所有数据,则不会发生这种情况。如果您从活动外部读取数据(应用程序类,可能直接从数据库或SharedPref读取),则数据将保持原样 如果不是这样,我的建议是创建如下内容:
private void invalidateData(){
// invalidate all relevant fields (set as null or 0)
}
在activity onDestroy方法上调用此方法请考虑调用finish方法的文档不能保证立即销毁。 但对于您的情况,您可以重写onPause方法。当活动变为隐藏时,它会自动调用。如果要使用此方法,您必须在onResume方法中初始化数据。 请注意,从中调用finish()方法的活动已被销毁,其所有资源已排队进行垃圾收集,并且此活动使用的所有内存将在下一个GC循环期间释放 如果确实要尽快撤消内存,请重写活动的onDestroy方法:
@Override
public void onDestroy() {
super.onDestroy();
Runtime.getRuntime().gc(); //This is the key
}
最后,问题与android无关,实际问题是
CustomViewUtilities.edited;
witch最初在每次private boolean edited=false时被实例化;
变为staticprivate static boolean edited=false;
因此它永远不会返回false,也不会被销毁。覆盖onDestroy()
方法,在此方法中,只需调用finish()
和Runtime.getRuntime().gc()
方法
必须为所有变量赋值NULL
我的代码:
@Override
public void onDestroy() {
super.onDestroy();
try{
Runtime.getRuntime().gc();
finish();
}catch (Exception e){
e.printStackTrace();
}
}
您不需要完成活动。在Adepter上使用setNotifyDataChange阅读关于
将启动模式设置为标准可能会有所帮助
@Override
public void onDestroy() {
super.onDestroy();
Runtime.getRuntime().gc(); //This is the key
}
@Override
public void onDestroy() {
super.onDestroy();
try{
Runtime.getRuntime().gc();
finish();
}catch (Exception e){
e.printStackTrace();
}
}