I'm trying to build a to-do list app in Android Studio that saves the list as a text file and then when you open the app again if there's a text file with stored tasks it will initialize the arraylist in the app with that data.
It was all working well with the arraylist and its adapter until I had to update the arraylist with the stored file. Now it prints but instead of printing the string with the task it prints a weird internal thing like "com.example.todolist.MyData@fe7bcc9"
I've looked around and can't quite find if I can use the same adapter twice (update it?) and generally any info on your experiences using this would be really helpful.
main java code:
package com.example.todolist;
import android.content.Context;
import android.os.Bundle;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.EditText;
import android.view.Menu;
import android.view.MenuItem;
import android.util.Log;
import java.io.*;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
 public class MainJava extends AppCompatActivity implements AdapterView.OnItemClickListener {
     // 1. Some variables and definitions
        ListView listView;
        ArrayList<MyData> arrayList = new ArrayList<>();
        MyAdapter adapter, adapter2;
        private EditText taskEntered;
        private int itemPos;
        private final String file = "list.txt";
        private String line;
        private OutputStreamWriter out;
     // 2. Method: The classic ON CREATE
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            // locate the widgets: edit text (to get string) and list view (to put string)
            taskEntered = (EditText) findViewById(R.id.enterTask);
            listView = findViewById(R.id.listView);
            // attach listener to list view
            listView.setOnItemClickListener(this);
            taskEntered.setText("");
            //hide title and icon in action bar  EDIT TO HIDE SAVE AND CLOSE
            ActionBar actionBar = getSupportActionBar();
            actionBar.setDisplayShowTitleEnabled(false);
            actionBar.setDisplayUseLogoEnabled(false);
            //open output stream
            //try {
               // out = new OutputStreamWriter(openFileOutput(file,MODE_PRIVATE)); // also try MODE_APPEND
          //  } catch (IOException e) {}
            readFromFile();
        }
     // 3. Method: ON CREATE OPTIONS MENU
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         getMenuInflater().inflate(R.menu.menu, menu);
         return true;
     }
     // 4. Method: ON OPTIONS SELECTED
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         int itemID = item.getItemId();  // get id of menu item picked
         switch (itemID) {
             case R.id.add :
                 addNewTask();   // prints entered task in list view
                 return true;
             case R.id.delete :
                 deleteTask();
                 return true;
             case R.id.update :
                 updateTask();
                 return true;
             case R.id.save :
                 saveToFile();
                 return true;
             case R.id.close :
                 saveToFile();
                 finish();
             default: super.onOptionsItemSelected(item);
         }
         return false;
     }
    // 5. Method: PRINT NEW TASK in list view and ADD NEW TASK to arrayList
     public void addNewTask() {
         // get string from the edit text
         String taskString = taskEntered.getText().toString();
         // create ArrayList values
         arrayList.add(new MyData(arrayList.size() +1, taskString));
         // TESTING: arrayList.add(new MyData(2, " Robert"));
         //create custom adapter and connect to ListView
         adapter = new MyAdapter(this, arrayList);
         listView.setAdapter(adapter);
         taskEntered.setText("");                          // clear edit text bar after adding item
     }
     // 5. Method:
     public void addNewTask(String string) {
         // create ArrayList values
         arrayList.add(new MyData(arrayList.size() +1, string));
         //create custom adapter and connect to ListView
         adapter = new MyAdapter(this, arrayList);
         listView.setAdapter(adapter);
     }
     // 6. Method: Listener, when you click on an item in list view it does this:
     // listener is passed into the position of the item that was clicked?
     public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            itemPos = position;
            // you click on an item in list view
         String task = arrayList.get(position).getName();      // get name of task
         int numTask = arrayList.get(position).getNum();        // get number of task
         // set edit text field to show the item you just clicked
         taskEntered.setText(numTask + " " + task);
     }
     // 7. Method: Delete a task
     public void deleteTask() {
         // remove the arrayList item in the position that was clicked
         arrayList.remove(itemPos);
         // loop through items and reassign numbers
         for (int i=0; i < arrayList.size(); i++){
             arrayList.get(i).setNum(i+1);
         }
         //create custom adapter and connect to ListView
         adapter = new MyAdapter(this, arrayList);
         listView.setAdapter(adapter);
         taskEntered.setText("");                                     // clearing edit text widget
     }
     // 7. Method: Update a task
     public void updateTask() {
         // get string from the edit text
         String taskString = taskEntered.getText().toString();
         String updatedString= taskString.substring(2);  // so that the task number is not repeated
         arrayList.get(itemPos).setName(updatedString);
         //create custom adapter and connect to ListView
         adapter = new MyAdapter(this, arrayList);
         listView.setAdapter(adapter);
         taskEntered.setText("");                                     // clearing edit text widget
     }
     // 8. Method: Save contents of app to a file
     public void saveToFile() {
         try {
             // writing!
             //open output stream try catch
             try {
                 out = new OutputStreamWriter(openFileOutput(file,MODE_PRIVATE)); // also try MODE_APPEND
             } catch (IOException e) {}
             // loop through items in ArrayList
             for (int i=0; i < arrayList.size(); i++){
                 line = arrayList.get(i).toString();        // grab each line from the to do list
                 out.write(line + " \n");             // write each line on TEXT file
             }
             out.close();                           // close output stream
         } catch (IOException e) {
             Log.e("IOTest", e.getMessage());
         }
     }
     // 9. Method: Read from file
     public void readFromFile() {
         // check if file already exists, if not - finish, if yes - open stream and update app with that
            // A) if file doesn't exist leave method
            if ( !fileExists(this, "list.txt") ){
                return;
            }
            // B) if file already exists, open a stream, read it, copy it to ToDoList app
            else {
                arrayList.clear();
                try {
                    // reading!
                    InputStream in = openFileInput(file);            // open stream for reading from file
                    InputStreamReader isr = new InputStreamReader(in);
                    BufferedReader reader = new BufferedReader(isr);
                    String str = null;
                    // loop to read lines from file and print in app
                    while ((str = reader.readLine()) != null) {      // str = each line in the text file OR MAYBE THIS STRING IS THE RAW CODE FROM EACH LINE
                        addNewTask(str);
                        //str.toString();
                        //arrayList.add(new MyData(arrayList.size() +1, str));    // create ArrayList value of the string in the text file
                       // adapter = new MyAdapter(this, arrayList);            // create custom adapter and connect to ListView
                        //listView.setAdapter(adapter);
                    }
                    reader.close();               //close input stream
                } catch (IOException e) {
                    Log.e("IOTest", e.getMessage());
                }
            }
     }
     // 10. Method: Check if file exists
     public boolean fileExists(Context context, String filename) {
         File file = context.getFileStreamPath(filename);
         if(file == null || !file.exists()) {
             return false;
         }
         return true;
     }
    }
Adapter.java code:
package com.example.todolist;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import androidx.appcompat.app.AppCompatActivity;
/*
 ADAPTER
  inflate xml file called row.xml
  get references (id's) for widgets in row.xml
  add each value on arrayList to its widget
 */
public class MyAdapter extends ArrayAdapter {
    private Context context;
    private ArrayList<MyData> arrayList;
    private TextView listNum, name, contactNum;
    // calling 3 arg constructor of parent class and storing values stored in
    public MyAdapter(Context context, ArrayList<MyData> arrayList) {
        super(context, 0, arrayList);
        this.context = context;
        this.arrayList = arrayList;
    }
    // all the action is in this getView method
    // calls layout inflater class and gives it the layout of the row
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // call inflater to create a View from an xml layout file
        convertView = LayoutInflater.from(context).inflate(R.layout.row, parent, false);
        // get references for row widgets
        listNum = convertView.findViewById(R.id.listNum);   // id´s of widgets in MyAdapter.java
        name = convertView.findViewById(R.id.task);
        // ArrayList provides values that go along in a row when getView is finished it goes through entire ArrayList and
        listNum.setText(" " + arrayList.get(position).getNum());
        name.setText(arrayList.get(position).getName());
        return convertView;
    }
}
my data code:
package com.example.todolist;
public class MyData {
    private int listNum;
    private String name;
    //constructors
    public MyData(int num, String name) {
        this.listNum = num;
        this.name = name;
    }
    //accessors and mutators
    public int getNum() {
        return listNum;
    }
    public void setNum(int num) {
        this.listNum = num;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
 
     
    