The application crashes when you try to add to ArrayAdapter

advertisements

I am working on an assignment for school, the instructions are to create a Bookmark app with two activities, one named BookNote which must be a List Activity and another called ManageActivity.

BookNote is to populate the List Activity on startup with data read from a file, if no file is present an example bookmark is created. Bookmarks can be added, edited, and deleted, but all typing must be done in ManageActivity. Whenever Booknote handles the data returned from ManageActivity it should alter the list.

The code I have now has comments showing my intentions for each function, but my current problem is that everytime I return to BookNote from ManageActivity, the app crashes with the error "Attempt to invoke virtual method 'void android.widget.ArrayAdapter.insert(java.lang.Object, int)' on a null object reference" when attempting to add or insert a new bookmark object into the ArrayAdapter.

BookNote Activity

import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;

public class BookNote extends ListActivity{
    private ArrayAdapter<Bookmark> adapter;
    private final String FILENAME = "bookmarks.txt";
    public String title = "EMPTY", url = "EMPTY", note = "EMPTY";
    public String bookmarkClicked ="";
    public int listViewID = 0;

    public boolean intentListener = false;
    public boolean addBookmarkClicked = false;

    /*When activity is called, list is populated by readData(), addBookmarkClicked is reset to false, intentLister is changed to true if returning from ManageActivity,
    if intentListener is true, addBookmarkClicked will be changed to true if AddBookmark is clicked from the BookNote menubar, a bookmark object will be created with information
    passed back from ManageActivity, and if addBookmarkClicked is true, the bookmark object will be added to the end of the list, otherwise it will be inserted in the same
    list element from which was chosen to edit.*/

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ArrayList<Bookmark> bookmarkList = readData();
        ArrayAdapter adapter = new ArrayAdapter<Bookmark>(this, android.R.layout.simple_list_item_1, bookmarkList);
        setListAdapter(adapter);

        addBookmarkClicked = false;
        intentListener = false;

        intentListener = getIntent().getBooleanExtra("listen", false);
        if(intentListener == true) {
            addBookmarkClicked = getIntent().getBooleanExtra("addClicked", false);
            title = getIntent().getExtras().getString("title");
            url = getIntent().getExtras().getString("url");
            note = getIntent().getExtras().getString("note");
            listViewID = getIntent().getExtras().getInt("listViewID");
            Bookmark bookmark = new Bookmark(title,url,note);
            Toast.makeText(getApplicationContext(), "Intent return: True", Toast.LENGTH_SHORT).show();

            if(addBookmarkClicked == true) {
                addBookmark(bookmark);
            }
            else {
                insertBookmark(bookmark, listViewID);
            }
            //writeData();
        }
    }

    //When list item is clicked, fill bookmarkClicked with values in list item, record item position, and call gotoManageActivity() to pass information to ManageActivity.

    public void onListItemClick(ListView listView, View view, int position, long id) {
        ListView myListView = getListView();
        Object itemClicked = myListView.getAdapter().getItem(position);
        Toast.makeText(getApplicationContext(), "Item clicked: " + itemClicked + "\nItem ID: " + id,Toast.LENGTH_SHORT).show();
        bookmarkClicked = itemClicked.toString();
        listViewID = position;
        gotoManageActivity();
    }

    //reads data when app runs and fills arrayadapter and list with items saved to bookmarks.txt
    private ArrayList<Bookmark> readData(){
        ArrayList<Bookmark> bookmarks = new ArrayList<>();

        try {
            FileInputStream fis = openFileInput(FILENAME);
            Scanner scanner = new Scanner(fis);
            if (scanner.hasNext()){
                String titleScan = scanner.nextLine();
                String urlScan = scanner.nextLine();
                String noteScan = scanner.nextLine();
                Bookmark bookmark = new Bookmark(titleScan, urlScan, noteScan);
                bookmarks.add(bookmark);
            }else{
                Bookmark bookmark = new Bookmark("Example Title", "Example URL", "Example Note");
                bookmarks.add(bookmark);
            }
            scanner.close();
        } catch (FileNotFoundException e) {
        }
        return bookmarks;
    }

    //If addBookmark menu item is clicked, this will be called to add a bookmark to the end of the ArrayAdapter.
    private void addBookmark(Bookmark bookmark){
        adapter.add(bookmark);
        //writeData();
    }

    //If a list item is clicked, any edits will be inserted back into the  ArrayAdapter in the same position of the item clicked.
    private void insertBookmark(Bookmark bookmark, int listViewID){
        adapter.insert(bookmark,listViewID);
        //writeData();
    }

    //Calls ManageActivity and reports information about app.
    public void gotoManageActivity(){
        Intent manageIntent = new Intent(this, ManageActivity.class);
        Bundle extras = new Bundle();
        extras.putString("bookmark", bookmarkClicked);
        extras.putBoolean("addBookmarkClicked", addBookmarkClicked);
        extras.putInt("listViewID", listViewID);
        manageIntent.putExtras(extras);
        startActivity(manageIntent);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is   present.
        getMenuInflater().inflate(R.menu.menu_book_note, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_add) {
            addBookmarkClicked = true;
            gotoManageActivity();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

ManageActivity

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.InputType;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

public class ManageActivity extends AppCompatActivity {

    private String title = "EMPTY", url = "EMPTY", note = "EMPTY";
    private boolean listener = true;
    private boolean addBookmarkClicked = false;

    /* When activity starts, check for addBookmarkClicked status, create book */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.manage_layout);

        addBookmarkClicked = getIntent().getBooleanExtra("addClicked", false);

        String bookmarkString = "";
        bookmarkString = getIntent().getExtras().getString("bookmark");
        if(bookmarkString != null && bookmarkString.length() > 0) {
            if (bookmarkString.length() != 0) {
                String[] stringArray = bookmarkString.split("\\n");
                title = stringArray[0];
                url = stringArray[1];
                note = stringArray[2];
                updateTextViews();
            }
        }
        else {
            updateTextViews();
        }
    }

    @Override
    public void onBackPressed(){
        Intent bookNoteIntent = new Intent(this, BookNote.class);
        startActivity(bookNoteIntent);
        Bundle extras = new Bundle();
        extras.putString("title", title);
        extras.putString("url", url);
        extras.putString("note", note);
        extras.putBoolean("listen", listener);
        extras.putBoolean("addBookmarkClicked", addBookmarkClicked);
        bookNoteIntent.putExtras(extras);
        startActivity(bookNoteIntent);
    }

    public void editButtonCall(View view){
        showNoteDialog();
        showURLDialog();
        showTitleDialog();
    }

    public void webButton(View view){
        if(url.length() != 0 && url != "EMPTY"){

        }
    }

    public void updateTextViews(){
        TextView titleTextView = (TextView) findViewById(R.id.titleTV);
        TextView urlTextView = (TextView) findViewById(R.id.urlTV);
        TextView noteTextView = (TextView) findViewById(R.id.noteTV);
        titleTextView.setText("Title: " + title);
        urlTextView.setText("URL: " + url);
        noteTextView.setText("Note: " + note);
    }

    //Show dialog and editText for user to assign title to bookmark.
    public void showTitleDialog(){
        AlertDialog.Builder titleBuilder = new AlertDialog.Builder(this);
        titleBuilder.setTitle("Enter Title");

        final EditText titleET = new EditText(this);
        titleET.setInputType(InputType.TYPE_TEXT_VARIATION_NORMAL);
        titleBuilder.setView(titleET);
        titleBuilder.setPositiveButton("Add", newDialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int i) {
                title = titleET.getText().toString();
                updateTextViews();
            }
        });
        titleBuilder.show();
    }

    //Show dialog and editText for user to assign note to bookmark.
    public void showNoteDialog(){
        AlertDialog.Builder noteBuilder = new AlertDialog.Builder(this);
        noteBuilder.setTitle("Enter Note");

        final EditText noteET = new EditText(this);
        noteET.setInputType(InputType.TYPE_TEXT_VARIATION_NORMAL);
        noteBuilder.setView(noteET);

        noteBuilder.setPositiveButton("Add", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                note = noteET.getText().toString();
                updateTextViews();
            }
        });

        noteBuilder.show();
    }

    //Show dialog and editText for user to assign url to bookmark.
    public void showURLDialog(){
        AlertDialog.Builder urlBuilder = new AlertDialog.Builder(this);
       urlBuilder.setTitle("Enter URL");

        final EditText urlET = new EditText(this);
        urlET.setInputType(InputType.TYPE_TEXT_VARIATION_NORMAL);
        urlBuilder.setView(urlET);

        urlBuilder.setPositiveButton("Add", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int i) {
                url = urlET.getText().toString();
                updateTextViews();
            }
        });
        urlBuilder.show();
    }
}


You are declaring a global and a local instance of adapter. In onCreate() method of BookNote Activity, remove the local instance. Change

ArrayAdapter adapter = new ArrayAdapter<Bookmark>(this, android.R.layout.simple_list_item_1, bookmarkList);

to

adapter = new ArrayAdapter<Bookmark>(this, android.R.layout.simple_list_item_1, bookmarkList);