Kayvonn1
Kayvonn1

Reputation: 19

How to save items inside an ArrayList when an app is restarted? (Android)

Whenever I restart my app, all the information I saved inside an ArrayList during its runtime is deleted. In addition, sometimes when I go to another activity and then come back from that second activity. The information is deleted again. I'm not sure what's causing this. I want the information to be permanently saved unless deleted by the user. Usually, the error I'm receiving are IndexOutOfBounds exception when I need to call an item from my ArrayList.

Main Activity Code:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView preset;
    private Button add;
    private ListView exercises;

    private ArrayList<String> exerciseName;
    public ArrayList<Exercise> Exercises;
    private MyAdapter adapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Exercises = new ArrayList<Exercise>();
        preset = findViewById(R.id.preset_title);
        add = findViewById(R.id.add_exercise);
        exercises = findViewById(R.id.exercises);
        exerciseName = FileHelper.readData(this);
        this.adapter = new MyAdapter(exerciseName, this, Exercises);
        exercises.setAdapter(adapter);
        add.setOnClickListener(this);


    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.add_exercise:
                final int CODE = 1;
                Intent i = new Intent(this, add_activity.class);
                startActivityForResult(i, CODE);
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch(requestCode) {
            case 1:
                if(resultCode == RESULT_OK && data != null) {
                    Bundle passBack = data.getExtras();
                    Exercise exercise = passBack.getParcelable("exercise");
                    adapter.addData(exercise);
                    adapter.list.add(exercise.getName());
                    FileHelper.writeData(exerciseName, this);
                    adapter.notifyDataSetChanged();
                }
            case 2:
                if (resultCode == RESULT_OK && data != null) {
                    Bundle passBack = data.getExtras();
                    Exercise exercise = passBack.getParcelable("exercise");
                    int position = passBack.getInt("position");
                    adapter.setData(exercise, position);
                    adapter.notifyDataSetChanged();
                }
        }
    }
}

Custom Adapter Code (where my ArrayList data is stored):

public class MyAdapter extends ArrayAdapter<String> {
    public ArrayList<String> list;
    private Context context;
    private TextView list_txt;
    private ArrayList<Exercise> data;


    public MyAdapter(ArrayList<String> records, Context context, ArrayList<Exercise> data) {
        super(context, 0, records);
        this.list = records;
        this.data = data;
        this.context = context;
    }

    public void addData(Exercise d){
        data.add(d);
    }

    public void setData(Exercise d, int position) {
        data.set(position, d);
    }


    @Override
    public View getView(final int position, View convertView, final ViewGroup parent) {
        if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.listview_custom, parent, false);
        }

        Button list_but = (Button) convertView.findViewById(R.id.list_but);
        TextView list_txt = (TextView) convertView.findViewById((R.id.list_txt));
        Button edit = (Button) convertView.findViewById(R.id.list_but2);
        Button start = (Button) convertView.findViewById(R.id.list_but3);
        list_txt.setText(list.get(position));

        edit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                final int CODE2 = 2;
                Activity origin = (Activity)context;
                Intent edit = new Intent(parent.getContext(), add_activity.class);
                Bundle newBundle = new Bundle();
                newBundle.putParcelable("exercise", data.get(position));
                newBundle.putInt("position", position);
                edit.putExtras(newBundle);
                origin.startActivityForResult(edit, CODE2);
            }
        });

        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent start = new Intent(parent.getContext(), timer_activity.class);
                start.putExtra("exercise", data.get(position));
                parent.getContext().startActivity(start);
            }
        });
        list_but.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AlertDialog.Builder alert = new AlertDialog.Builder(context);
                alert.setTitle("Delete?");
                alert.setMessage("Are you sure you want to delete this exercise?");
                alert.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        list.remove(position);
                        try {
                            data.remove(position);
                        } catch(IndexOutOfBoundsException ex) {

                        }
                        notifyDataSetChanged();
                    }
                });
                alert.setNegativeButton("No", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {

                    }
                });
                alert.create().show();
            }
        });
        return convertView;
    }
}

Upvotes: 0

Views: 37

Answers (1)

iknow
iknow

Reputation: 9852

Every time You destroy activity You are losing all saved data in ListView. You have to save it before destroying and restore when You start an activity. You can do it with gson and SharedPreferences.

In Your MainActivity override onSaveInstanceState and inside this method save all Your exercises from Exercises list using gson.

Gson gson = new Gson();  
String exercisesJSON = gson.toJson(Exercises); 

SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("KEY_BETTER_USE_CONST", exercisesJSON);
editor.commit();

And then in onCreate restore this data:

SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);
String exercisesJSON = sharedPref.getInt("KEY_BETTER_USE_CONST", "DEFAULT_VALUE_EMPTY");

//check if exercisesJSON is equal to "DEFAULT_VALUE_EMPTY" if yes, init array as empty, if not deserialize it using gson

Gson gson = new Gson();  
Exercises[] exercises = gson.fromJson(exercisesJSON, Exercise[].class); 

Haven't debugged this code but I think it should look something like this. I based on: Gson — Mapping of Arrays and Lists of Objects

Upvotes: 1

Related Questions