Values lost in previous Activity when I hit back b

2019-02-23 13:05发布

问题:

So I have a weird problem. I have 2 Activities I'm working on. One of the Activities displays a ListView whose data is grabbed via a long Extra I use to fetch the results via a WHERE clause in the database.query. The other Activity is called when a ListView item is clicked, allowing someone to add something to the database for the ListView.

The activity names are DaysActivity.java (the activity with the listview) and DayAddActivity.java (the Activity that allows someone to add a day, which then shows up in the DaysActivity.java ListView).

The problem I'm having is, when I finish() DayAddActivity.java it goes back to DaysActivity and the ListView is still there fully populated. However, if I hit the back button in DayAddActivity.java (the button to the left of the title in the action bar with my app icon), when it goes back to DaysActivity.java, the ListView is empty/gone.

Heres the code for both:

DaysActivity.java:

package com.gauvion.gfit;

import android.annotation.SuppressLint;
import android.app.ListActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

public class DaysActivity extends ListActivity {

    private DaysDataSource datasource;
    private SimpleCursorAdapter dataAdapter;
    private boolean isEditing = false;
    private Toast toast_deleted;
    private String[] columns = new String[] { MySQLiteHelper.COLUMN_NAME, MySQLiteHelper.COLUMN_DAY };
    private int[] to;
    private long routineDataID;
    private String routineDataName;

    @SuppressLint("ShowToast")
    @Override
    public void onCreate(Bundle savedInstanceState) {       
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_days); 

        routineDataID = getIntent().getLongExtra("routineDataID", 0);
        routineDataName = getIntent().getStringExtra("routineDataName");
        setTitle(routineDataName);

        toast_deleted = Toast.makeText(this, "", Toast.LENGTH_SHORT);
        datasource = new DaysDataSource(this);
        datasource.open();

        Cursor cursor = datasource.fetchAllDays(routineDataID);
        to = new int[] { R.id.listitem_day_name, R.id.listitem_day_day };
        dataAdapter = new SimpleCursorAdapter(this, R.layout.listitem_day, cursor, columns, to, 0);
        setListAdapter(dataAdapter);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {     
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.activity_days, menu);
        return true;        
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {     
        Cursor cursor = datasource.fetchAllDays(routineDataID);
        switch (item.getItemId()) {
        case R.id.button_days_add:
            Intent startDayAdd = new Intent(this, DayAddActivity.class);
            startDayAdd.putExtra("routineDataID", routineDataID);
            this.startActivity(startDayAdd);
            return true;

        case R.id.button_days_edit:
            to = new int[] { R.id.listitem_day_edit_name, R.id.listitem_day_edit_day };
            dataAdapter = new SimpleCursorAdapter(this, R.layout.listitem_day_edit, cursor, columns, to, 0);
            setListAdapter(dataAdapter);

            isEditing = true;
            invalidateOptionsMenu();
            return true;

        case R.id.button_days_edit_done:
            to = new int[] { R.id.listitem_day_name, R.id.listitem_day_day };
            dataAdapter = new SimpleCursorAdapter(this, R.layout.listitem_day, cursor, columns, to, 0);
            setListAdapter(dataAdapter);

            isEditing = false;
            invalidateOptionsMenu();
            return true;

        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);

        menu.findItem(R.id.button_days_edit).setVisible(!isEditing);
        menu.findItem(R.id.button_days_edit_done).setVisible(isEditing);

        return true;
    }

    @Override
    protected void onResume() {
        datasource.open();
        Cursor cursor = datasource.fetchAllDays(routineDataID);
        dataAdapter.changeCursor(cursor);

        super.onResume();
    }

    @Override
    protected void onPause() {
        datasource.close();
        super.onPause();
    }

} 

DayAddActivity.java:

package com.gauvion.gfit;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
import android.support.v4.app.NavUtils;

public class DayAddActivity extends Activity {
    private RoutinesDataSource datasource;
    private EditText dayName;
    private Spinner dayDay;
    private Button saveButton;
    private long routineDataID;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_day_add);
        routineDataID = getIntent().getLongExtra("routineDataID", 0);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_day_add, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    public void cancelDay(View view) {
        this.finish();
    }

}

The cancelDay() function is called when a "Cancel" button is clicked in activity_day_add.xml. Like I said, when I click the "Cancel" button inside of DayAddActivity.java, it goes back to DaysActivity.java and the ListView is fine. All data is there. However, if I press the back button in the action bar (the button containing a back arrow and my app icon beside the title of the Activity) the ListView for DaysActivity.java is empty/gone, and the title is also empty (because this is also generated through an Extra String value).

回答1:

Your cursors are not managed by the activity, this can cause a memory leak or even ANR. You should consider using a loader to populate a list using a cursor. You can find an example here :http://developer.android.com/guide/components/loaders.html.

Loaders work better as they don't freeze the app when the connexion to the database is obtained and they will be passed from one instance of your activity to another, preventing memory leaks and reusing resources.

But again, as in your previous post : Extras seem to be lost onResume(), you should understand the link between onSaveInstanceState and onCreate to pass arguments to the future self of your activity. Look at this post, the answer with the biggest score : onSaveInstanceState () and onRestoreInstanceState ().



回答2:

It seems like your Context has some problems in "this.startActivity(startDayAdd);" line. try using "DaysActivity.this.startActivity(startDayAdd);". if it doesnot work then use breakpoints to see line by line execution.