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时被实例化;
变为static
private 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();
    }
}