Android Database in AsyncTask in Fragment

487 views Asked by At

I have a DbHelper Class which extends SQLiteOpenHelper. I do Some Download and update the Database inside an Asynctask. Inside an activity i got no problem and code works fine, but when i use the ASynctask class inside a fragment problems occurs.

usually wherever i use a context an Exception happened, Especially with dbHelper.ClearDB()

Error:

DB Read ERROR:java.lang.NullPointerException:
 Attempt to invoke     virtual method 'java.util.ArrayList x.database.DBHelper.getAllItems()' on a null object reference

Here's the code :

public class StaggeredFragment extends Fragment
{


private DBHelper dbHelper;
private SharedPreferences preferences;
private ArrayList<DisItem> savedData;
private final String LINK1 = "myLink";

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    dbHelper = new DBHelper(getActivity().getApplicationContext());
    preferences = getActivity().getSharedPreferences("pid", Context.MODE_PRIVATE);

    new LoaderAsyncTask("ALL").execute();
}

class LoaderAsyncTask extends AsyncTask<Void, Void, Boolean> {

    String brand;

    LoaderAsyncTask(String brand) {
        this.brand = brand;
    }


    @Override
    protected Boolean doInBackground(Void... params) {

        Log.d(TAG,"RUnning");

        String fetched;
        InputStream is = null;

        //Store Current Data before Sync
        try {
            savedData = dbHelper.getAllItems();
        }catch (Exception e)
        {
            Log.d(TAG,"DB Read ERROR:"+e.toString());
            return false;
        }

        try {
            dbHelper.ClearDB();
        }catch (Exception e)
        {
            Log.d(TAG,"DB Clear ERROR:"+e.toString());
            return false;
        }

//        Open connection to server for html
        try {
            is = urlStream(LINK1);
        } catch (Exception e) {
            Log.e(TAG, "HTTP Error " + e.toString());
            return false;
        }

 //        Fetch HTML Data
        try {
            fetched = readIt(is);
           // Log.d("fetched", fetched);
        } catch (Exception e) {
            Log.e(TAG, "Buffer Error " + e.toString());
            return false;
        }

  //        Parsing JSON
        try {
            if (!fetched.isEmpty())
                InitialsJson(fetched);
        }catch (JSONException e) {
            Log.e(TAG, "JSON Error " + e.toString());
            return false;
        }


        return true;
    }

    @Override
    protected void onPostExecute(Boolean aBoolean) {
        super.onPostExecute(aBoolean);
        if(!aBoolean)
            RestoreData();
    }

}

private void InitialsJson(String fetched) throws JSONException
{
    JSONObject jsonObject = new JSONObject(fetched);

    if (jsonObject.getInt("success") == 1) {
        JSONArray array = jsonObject.getJSONArray("data");
        for (int i = 0; i<array.length() ; i++) {

            JSONObject object = array.getJSONObject(i);
            DisItem disItem = new DisItem();
               disItem.setPid(object.getString("pid"));
 disItem.setLiked(preferences.getBoolean(String.valueOf(disItem.getPid()), false));

            Log.d(TAG, disItem.toString());
            dbHelper.insert(disItem);

        }


    }
}

This is Databace getallItems function

      public ArrayList<DisItem> getAllItems()
      {
       SQLiteDatabase db = this.getReadableDatabase();
       Cursor cursor = db.rawQuery("select * from " + DIS_TABLE_NAME + "", null);
        ArrayList<DisItem> arrayList = new ArrayList<>();
       cursor.moveToFirst();

    while (! cursor.isAfterLast())
    {
        DisItem disItem = new DisItem(cursor);
        arrayList.add(disItem);
        cursor.moveToNext();
    }
    return arrayList;

}
2

There are 2 answers

0
Amin On

you cant access more than one SharedPreferences or SQLiteOpenHelper in Parallel.

1
Zubair Ahmed On

I tried your code with same scenario in a small JUnit Test and it shows me that you have not initialized your ArrayList<DisItem> correctely in getAllItems() method may be thats why you are getting nullPointerException that is

Replace

ArrayList<DisItem> arrayList = new ArrayList<>();

With

ArrayList<DisItem> arrayList = new ArrayList<DisItem>();'

I corrected this thing and run the test again with some dummy values and it showed me correct result like:

public class Test 
{   
    private ArrayList<DisItem> savedData;

    @org.junit.Test
    public void test() throws Exception 
    {       
        savedData = getAllData();

        for(int a = 0; a < savedData.size(); a++){
            System.out.println("ArrayList Data A= " + savedData.get(a).getA() + " B = " + savedData.get(a).getB());
        }
    }
}

private ArrayList<DisItem> getAllData()
{
    ArrayList<DisItem> arrayList = new ArrayList<DisItem>();

    DisItem disItem = new DisItem();

    disItem.setA("AAAAAA");
    disItem.setB("BBBB");

    arrayList.add(disItem);

    return arrayList;
}

private class DisItem
{
    String a, b;

    public void setA(String a)
    {
        this.a = a;
    }

    public void setB(String b)
    {
        this.b = b;
    }

    public String getA()
    {
        return this.a;
    }

    public String getB()
    {
        return this.b;
    }
}

Output:

ArrayList Data A= AAAAAA B = BBBB