George Brooks
George Brooks

Reputation: 199

Android: SQLiteDatabase

I have created an SQLiteDatabase that holds information from user input. The user inputs data about their own recipe for a meal they want to share with others over facebook. This user data is stored and then displayed inside a listview. This works fine for the most part but when the listview is scrolled to observe more entries, a nullpointer occurs. I store 3 types of text information into this database but I only want the listview to display the entryID of the rows and display the rest of the information when the item is clicked.

The error message:

enter image description here

This is the adapter class it refers to:

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 java.util.List;


public class RecipeAdapter extends ArrayAdapter {

List list = new ArrayList();

public RecipeAdapter(Context context, int resource) {
    super(context, resource);
}


public void add(Recipe object) {
    list.add(object);
    super.add(object);
}

@Override
public int getCount() {
    return list.size();
}

@Override
public Object getItem(int position) {
    return list.get(position);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    RecipeHolder recipeHolder;
    if(row == null){

        LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row = layoutInflater.inflate(R.layout.display_entry_row,parent,false);
        recipeHolder = new RecipeHolder();
        recipeHolder.tx_id = (TextView)row.findViewById(R.id.t_id);

    }
    else{

        recipeHolder = (RecipeHolder) row.getTag();

    }

    Recipe recipe = (Recipe)getItem(position);

    recipeHolder.tx_id.setText(recipe.getId_entry().toString());

    return row;
}

static class RecipeHolder{

    TextView tx_id;

}
}

This is the line it is referring to:

recipeHolder.tx_id.setText(recipe.getId_entry().toString());

The Recipe Task with getter and setter:

public class Recipe {

private String id_entry;

public Recipe(String id_entry){

    this.setId_entry(id_entry);

}

public String getId_entry() {
    return id_entry;
}

public void setId_entry(String id_entry) {
    this.id_entry = id_entry;
}
}

And if needed my background task for the database itself:

 import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.widget.ListView;
import android.widget.Toast;


public class BackgroundTask extends AsyncTask<String, Recipe, String> {

Context ctx;
RecipeAdapter mRecipeAdapter;
Activity activity;
ListView listView;
BackgroundTask(Context ctx){
    this.ctx = ctx;
    activity = (Activity)ctx;
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
}

@Override
protected String doInBackground(String... params) {

    String method = params[0];
    DatabaseOperations dbOperations = new DatabaseOperations(ctx);

    //adds information into database
    if (method.equals("add_information")){

        String entry = params[1];
        String ingred = params [2];
        String direc = params [3];
        SQLiteDatabase db = dbOperations.getWritableDatabase();
        dbOperations.putInformation(db, entry, ingred, direc);
        return "One Row Inserted";
    }
    //gets information from database and places inside listview
    else if (method.equals("get_info")){

        listView = (ListView) activity.findViewById(R.id.listVrecipe);
        SQLiteDatabase db = dbOperations.getReadableDatabase();
        Cursor cursor = dbOperations.getInformation(db);
        mRecipeAdapter = new RecipeAdapter(ctx,R.layout.display_entry_row);
        String entry;
        //loops through all row information
        while (cursor.moveToNext()){

            //grabs entry id
            entry = cursor.getString(cursor.getColumnIndex(TableData.TableInfo.EntryID));
            Recipe recipe = new Recipe(entry);
            publishProgress(recipe);

        }
        return "get_info";
    }
    return null;
}

@Override
protected void onProgressUpdate(Recipe... values) {

    mRecipeAdapter.add(values[0]);


}

@Override
protected void onPostExecute(String result) {

    //after execution update listview with new entries
    if(result.equals("get_info")){

        listView.setAdapter(mRecipeAdapter);

    }
    else{

        Toast.makeText(ctx,result, Toast.LENGTH_LONG).show();

    }



}
}

Upvotes: 0

Views: 49

Answers (1)

Ferdous Ahamed
Ferdous Ahamed

Reputation: 21766

As per your attached image, its states that you are getting NullPointerException at your adapters getView() method.

From my point of view, there are two possibilities.

1. RecipeHolder is null, as you did not set tag to recipeHolder by using row.setTag(recipeHolder).

2. May be Recipe object is null.

When you are using ArrayAdapter, its best practice to use this as below:

Update your RecipeAdapter as below:

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 java.util.List;


public class RecipeAdapter extends ArrayAdapter<Recipe> {


    public RecipeAdapter(Context context, int resource, ArrayList<Recipe> list) {
        super(context, resource, list);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        RecipeHolder recipeHolder;

        if(convertView == null){

            LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.display_entry_row,parent, false);

            recipeHolder = new RecipeHolder();
            recipeHolder.tx_id = (TextView) convertView.findViewById(R.id.t_id);

            convertView.setTag(recipeHolder);
        }
        else{
            recipeHolder = (RecipeHolder) convertView.getTag();
        }

        Recipe recipe = (Recipe) getItem(position);

        recipeHolder.tx_id.setText(recipe.getId_entry().toString());

        return row;
    }

    static class RecipeHolder {

        TextView tx_id;
    }
}

Update BackgroundTask as below:

import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.widget.ListView;
import android.widget.Toast;

public class BackgroundTask extends AsyncTask<String, Recipe, String> {

    Context ctx;
    RecipeAdapter mRecipeAdapter;
    Activity activity;
    ListView listView;

    List<Recipe> listRecipe;

    BackgroundTask(Context ctx){
        this.ctx = ctx;
        activity = (Activity)ctx;
        listRecipe = new ArrayList<Recipe>();
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... params) {

        String method = params[0];
        DatabaseOperations dbOperations = new DatabaseOperations(ctx);

        //adds information into database
        if (method.equals("add_information")){

            String entry = params[1];
            String ingred = params [2];
            String direc = params [3];
            SQLiteDatabase db = dbOperations.getWritableDatabase();
            dbOperations.putInformation(db, entry, ingred, direc);
            return "One Row Inserted";
        }
        //gets information from database and places inside listview
        else if (method.equals("get_info")){

            listView = (ListView) activity.findViewById(R.id.listVrecipe);
            SQLiteDatabase db = dbOperations.getReadableDatabase();
            Cursor cursor = dbOperations.getInformation(db);

            // Adapter
            mRecipeAdapter = new RecipeAdapter(ctx, R.layout.display_entry_row, listRecipe);
            String entry;

            //loops through all row information
            while (cursor.moveToNext()){

                //grabs entry id
                entry = cursor.getString(cursor.getColumnIndex(TableData.TableInfo.EntryID));
                Recipe recipe = new Recipe(entry);

                // Add recipe to list
                listRecipe.add(recipe);
                mRecipeAdapter.notifyDataSetChanged();

                //publishProgress(recipe);
            }
            return "get_info";
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Recipe... values) {

        //mRecipeAdapter.add(values[0]);
    }

    @Override
    protected void onPostExecute(String result) {

        //after execution update listview with new entries
        if(result.equals("get_info")){
            listView.setAdapter(mRecipeAdapter);
        } else {
            Toast.makeText(ctx,result, Toast.LENGTH_LONG).show();
        }
    }
}

Hope this will help~

Upvotes: 1

Related Questions