在离线模式下读取存储的数据

时间:2016-09-30 10:49:22

标签: java android json sqlite

在过去的两天里,我遇到了一个小问题。让我先解释一下情况。我从我的服务器获取一些数据(当然是JSON对象),将它们存储在数据库中并在回收站视图中显示它们。

现在我想尝试一些有趣的事情。 Wifi关闭时应显示数据。我认为我不会有任何问题,因为从sqlite数据库读取的数据。但不知何故,在这种情况下,我的屏幕上没有显示任何内容。

这是我的代码:

AnnouncementsFragment

public class AnnouncementsFragment extends Fragment {
public String titleForSQLite;
public String imageForSQLite;
public String articleForSQLite;
public static final String TAG = "AelApp";
private ArrayList<AnnouncementsModel> listItemsList;
private static final String IMAGE_URL = "http://www.theo-android.co.uk/ael/cms/announcement_images/";
AnnouncementsModel item;
RecyclerView myList;
AnnouncementsDatabaseHandler dba;
Context mContext;
private ArrayList<AnnouncementsModel> dbAnnouncements = new ArrayList<>();
private AnnouncementsAdapter announcementsAdapter;
public static final String ANNOUNCMENT_TAG = "ANNOUNCEMENT_FRAGMENT";
public AnnouncementsFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    getActivity().setTitle("Ανακοινώσεις");

    View rootView = inflater.inflate(R.layout.fragment_announcements, container, false);
    listItemsList = new ArrayList<>();


    dba = new AnnouncementsDatabaseHandler(getActivity());
    myList = (RecyclerView) rootView.findViewById(R.id.listview_announcements);

        final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
        myList.setHasFixedSize(true);
        myList.setLayoutManager(linearLayoutManager);
        announcementsAdapter = new AnnouncementsAdapter(getActivity(), listItemsList);
        myList.setAdapter(announcementsAdapter);


        updateAnnouncementsList();

        storingDataToSQlite();


    return rootView;
}


public void updateAnnouncementsList() {
    listItemsList.clear();


        // Instantiate the RequestQueue.
        RequestQueue queue = Volley.newRequestQueue(getActivity());

        // Request a string response from the provided URL.
        JsonArrayRequest jsObjRequest = new JsonArrayRequest(Request.Method.GET, URL.GET_ANNOUNCEMENTS, new Response.Listener<JSONArray>() {

            @Override
            public void onResponse(JSONArray response) {

                Log.d(TAG, response.toString());
                //hidePD();

                // Parse json data.
                // Declare the json objects that we need and then for loop through the children array.
                // Do the json parse in a try catch block to catch the exceptions
                try {

                    for (int i = 0; i < response.length(); i++) {

                        JSONObject post = response.getJSONObject(i);

                        item = new AnnouncementsModel();
                        item.setAnnouncement_title(post.getString("title"));
                        item.setAnnouncement_image(IMAGE_URL + post.getString("announcement_image"));
                        item.setAnnouncement_article(post.getString("article"));

                        listItemsList.add(item);

                        //Here I store the json strings.
                        titleForSQLite = post.getString("title");
                        imageForSQLite = post.getString("announcement_image");
                        articleForSQLite = post.getString("article");

                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                // Update list by notifying the adapter of changes
                announcementsAdapter.notifyDataSetChanged();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                VolleyLog.d(TAG, "Error: " + error.getMessage());
                //hidePD();
            }
        });
        queue.add(jsObjRequest);

}
/*
* A method that add data in the SQlite database. It is found in AnnouncementsDatabaseHandler class
*/
public void storingDataToSQlite(){

    AnnouncementsModel myAnnouncements = new AnnouncementsModel();

    myAnnouncements.setAnnouncement_title(titleForSQLite);
    myAnnouncements.setAnnouncement_title(imageForSQLite);
    myAnnouncements.setAnnouncement_article(articleForSQLite);

    dba.addAnnouncements(myAnnouncements);
    fetchDataFromDB();
    dba.close();

}
/*
* A method that reads data from the database. It is found in AnnouncementsDatabaseHandler class
*/
public void fetchDataFromDB() {

    ArrayList<AnnouncementsModel> membersDB = dba.getAnnouncements();

    for(int i=0; i<membersDB.size();i++){
        String id = membersDB.get(i).getAnnouncement_id();
        String mTitle = membersDB.get(i).getAnnouncement_title();
        String mArticle = membersDB.get(i).getAnnouncement_article();

        String image = membersDB.get(i).getAnnouncement_image();

        AnnouncementsModel f = new AnnouncementsModel();

        f.setAnnouncement_id(id);
        f.setAnnouncement_title(mTitle);
        f.setAnnouncement_article(mArticle);
        f.setAnnouncement_image(image);

        dbAnnouncements.add(f);

    }
    dba.close();
  }
}

在我的webservice方法中,我从响应中提取json字符串。(也许我应该从ArrayList中读取字符串?)

                        //Here I store the json strings.
                        titleForSQLite = post.getString("title");
                        imageForSQLite = post.getString("announcement_image");
                        articleForSQLite = post.getString("article");

接下来,我在数据库中添加了titleForSQLite,imageForSQLite,articleForSQLite。

 public void storingDataToSQlite(){

    AnnouncementsModel myAnnouncements = new AnnouncementsModel();

    myAnnouncements.setAnnouncement_title(titleForSQLite);
    myAnnouncements.setAnnouncement_title(imageForSQLite);
    myAnnouncements.setAnnouncement_article(articleForSQLite);

    dba.addAnnouncements(myAnnouncements);
    fetchDataFromDB();
    dba.close();

}

最后我读了它们

public void fetchDataFromDB() {

    ArrayList<AnnouncementsModel> membersDB = dba.getAnnouncements();

    for(int i=0; i<membersDB.size();i++){
        String id = membersDB.get(i).getAnnouncement_id();
        String mTitle = membersDB.get(i).getAnnouncement_title();
        String mArticle = membersDB.get(i).getAnnouncement_article();

        String image = membersDB.get(i).getAnnouncement_image();

        AnnouncementsModel f = new AnnouncementsModel();

        f.setAnnouncement_id(id);
        f.setAnnouncement_title(mTitle);
        f.setAnnouncement_article(mArticle);
        f.setAnnouncement_image(image);

        dbAnnouncements.add(f);

    }
    dba.close();
}

那么为什么我遇到了我之前描述的问题呢?由于所有内容都存储在数据库中,因此数据应该同时读取ON和OFF的情况,对吗?有什么想法吗?

这是我的sqlite db代码。

public class AnnouncementsDatabaseHandler extends SQLiteOpenHelper {

private final ArrayList<AnnouncementsModel> announcementsModelArrayList = new ArrayList<>();

public AnnouncementsDatabaseHandler(Context context) {
    super(context, Constants.DATABASE_NAME, null, Constants.DATABASE_VERSION);
}
/*
* This callback method creates the database
*/
@Override
public void onCreate(SQLiteDatabase db) {

    String CREATE_ANNOUNCEMENTS_TABLE = "CREATE TABLE IF NOT EXISTS " + AnnouncementsConstants.TABLE_NAME +
            "(" + AnnouncementsConstants.KEY_ID + " INTEGER PRIMARY KEY, " + AnnouncementsConstants.ANNOUNCEMENT_TITLE+
            " TEXT, "  +  AnnouncementsConstants.ANNOUNCEMENT_image + " TEXT, " + AnnouncementsConstants.ANNOUNCEMENT_article + " TEXT);";



    db.execSQL(CREATE_ANNOUNCEMENTS_TABLE);
}

@Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
    db.execSQL("DROP TABLE IF EXISTS " + AnnouncementsConstants.TABLE_NAME);

    onCreate(db);
}
/*
*Add contents to table. Those contents are json strings that
*are retrieved from the server!
*/
public void addAnnouncements(AnnouncementsModel announcementsModel) {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(AnnouncementsConstants.KEY_ID,announcementsModel.getAnnouncement_id());
    values.put(AnnouncementsConstants.ANNOUNCEMENT_article, announcementsModel.getAnnouncement_title());
    values.put(AnnouncementsConstants.ANNOUNCEMENT_image, announcementsModel.getAnnouncement_title());
    values.put(AnnouncementsConstants.ANNOUNCEMENT_article, announcementsModel.getAnnouncement_article());


    db.insertWithOnConflict(AnnouncementsConstants.TABLE_NAME, AnnouncementsConstants.KEY_ID, values,
            SQLiteDatabase.CONFLICT_REPLACE);
    db.close();

    Log.d("Theo", "heeeey!data saved");
}
/*
* This method allows to read the stored data,and returns an
* array list.
*/
public ArrayList<AnnouncementsModel> getAnnouncements() {

    String select_query = "SELECT * " + AnnouncementsConstants.TABLE_NAME;

    SQLiteDatabase db = this.getReadableDatabase();

    Cursor cursor = db.query(Constants.TABLE_NAME, new String[]{
                    AnnouncementsConstants.KEY_ID, AnnouncementsConstants.ANNOUNCEMENT_TITLE, AnnouncementsConstants.ANNOUNCEMENT_article
            ,AnnouncementsConstants.ANNOUNCEMENT_image}, null, null, null, null,
            Constants.KEY_ID + " DESC");

    if (cursor.moveToFirst()) {
        do {

            AnnouncementsModel m = new AnnouncementsModel();
            m.setAnnouncement_title(cursor.getString(cursor.getColumnIndex(AnnouncementsConstants.ANNOUNCEMENT_TITLE)));
            m.setAnnouncement_image(cursor.getString(cursor.getColumnIndex(AnnouncementsConstants.ANNOUNCEMENT_image)));
            m.setAnnouncement_article(cursor.getString(cursor.getColumnIndex(AnnouncementsConstants.ANNOUNCEMENT_article)));
            m.setAnnouncement_id(cursor.getString(cursor.getColumnIndex(AnnouncementsConstants.KEY_ID)));


            announcementsModelArrayList.add(m);
        }while(cursor.moveToNext());


    }
    return announcementsModelArrayList;
} 

谢谢,

西奥。

3 个答案:

答案 0 :(得分:1)

  1. 一个问题是,titleForSQLite,imageForSQLite,articleForSQLite值仅填充数据流中的最后一个值,因为它们位于for循环中。
  2. 检查您的dba对象是否已准备好读写数据库。

答案 1 :(得分:0)

我认为您的选择查询错误

应该是

String select_query = "SELECT * from " + AnnouncementsConstants.TABLE_NAME;

从服务器

收到数据后,请调用以下方法表单进行循环

storingDataToSQlite();

和fetchDataFromDB();在for循环结束后......或者如果数据已经存在,你也可以从oncreate调用这个方法

在Oncreate中添加以下代码

if(isOnline)
{
  // get data from server
}else{
  // fetch data from db
}

答案 2 :(得分:-2)

  

试试这个

public void fetchDataFromDB() {

ArrayList<AnnouncementsModel> membersDB = dba.getAnnouncements();

for(int i=0; i<membersDB.size();i++){
     Cursor cursor = database.query(YOUR_TABLE_NAME,YOURCOLUMN_NAME[0],null, null, null, null, null, null);
    if (cursor.moveToFirst()) {
        while (!cursor.isAfterLast()) {
            AnnouncementsModel f = new AnnouncementsModel();   
            f.setAnnouncement_id(cursor.getInt(cursor.getColumnIndex("this is db key for id")));
           f.setAnnouncement_title(cursor.getString(cursor.getColumnIndex("title key")));
           f.setAnnouncement_article(cursor.getString(cursor.getColumnIndex("article key")));
     dbAnnouncements.add(f);
      }
    }
 }
dba.close();
}