【问题标题】:Android Database in AsyncTask in FragmentFragment 中 AsyncTask 中的 Android 数据库
【发布时间】:2015-06-10 12:02:28
【问题描述】:

我有一个扩展SQLiteOpenHelper 的 DbHelper 类。 我做了一些下载并更新Asynctask 中的数据库。 在活动中我没有问题,代码工作正常, 但是当我在片段中使用 ASynctask 类时会出现问题。

通常在我使用上下文的任何地方都会发生异常,尤其是dbHelper.ClearDB()

错误:

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

代码如下:

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);

        }


    }
}

这是Databace getallItems 函数

      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;

}

【问题讨论】:

标签: android sqlite android-fragments android-asynctask sqliteopenhelper


【解决方案1】:

我在一个小型 JUnit 测试中用相同的场景尝试了你的代码,它告诉我你没有在 getAllItems() 方法中正确初始化你的 ArrayList&lt;DisItem&gt; 可能这就是你得到 nullPointerException 的原因

替换

ArrayList&lt;DisItem&gt; arrayList = new ArrayList&lt;&gt;();

ArrayList&lt;DisItem&gt; arrayList = new ArrayList&lt;DisItem&gt;();'

我纠正了这个问题并使用一些虚拟值再次运行测试,它显示了正确的结果,例如:

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;
    }
}

输出:

ArrayList Data A= AAAAAA B = BBBB

【讨论】:

  • 谢谢 Zubair,这个问题与 Android Context 或 Database Leaking 而不是 java Language 相关,再次感谢。
【解决方案2】:

您不能同时访问多个 SharedPreferences 或 SQLiteOpenHelper。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    相关资源
    最近更新 更多