如何停止从Web服务获取重复数据

时间:2014-08-11 08:19:36

标签: android android-listview android-contentprovider

我有一个Android项目,需要使用从Web服务获取的数据更新listview,但是这些数据将首先保存到本地数据库,然后使用内容提供程序从本地数据库提供给listview。我成功实现了这个要求,只是列表视图显示了相同数据的多个集合。也就是说,如果您运行应用程序5次,列表视图中将显示五组相同的数据。

我的问题是我在哪里以及如何实现某种计数器或循环,以确保只显示一组数据。

以下是我的实施步骤

  1. Fragment使用Loader API从内容加载数据 Provider,这里是onCreateLoader()

    public Loader<Cursor> onCreateLoader(int loaderId, Bundle arg) {
    return (new CursorLoader(getActivity(), Provider.Programs.CONTENT_URI,
            PROJECTION, null, null, null));
    

    }

  2. 在onCreateLoader之后,适配器会像这样刷新

    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    mAdapter.swapCursor(cursor);
    

    }

  3. 在Content Provider类中,我初始化本地数据库和 调用执行Web服务调用的AsyncTask

    public boolean onCreate() {
    
    dbhelper = new LocalDatabase(getContext());
    startWebService();
    return((dbhelper == null) ? false : true);
    

    }

    private void startWebService(){
    HttpAsyncTask asyncTask = new HttpAsyncTask();
    asyncTask.execute();            
    

    }

  4. 然后在AsyncTask中我从REST端点获取数据,解析它然后调用Content Provider类的Insert方法将数据添加到数据库并通知提供者数据已更改

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            ContentValues values = new ContentValues();
            try {
                JSONArray jsonArray = new JSONArray(result);
                int lenght = jsonArray.length();
    
                for (int i = 0; i < jsonArray.length(); i++) {
                  JSONObject jsonObject = jsonArray.getJSONObject(i);
                  String name = jsonObject.getString("name");
                  values.put(Programs.NAME, name);
                  insert(Programs.CONTENT_URI, values);
    
                }               
                Log.i("Data Changed", "Data changed " + lenght);
                getContext().getContentResolver().notifyChange(Programs.CONTENT_URI, null);
                } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    

    以下是我从数据库中获取数据的方法

    @Override
        public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
                String sort) {
                SQLiteQueryBuilder qb=new SQLiteQueryBuilder();
                qb.setTables(TABLE);
                String orderBy;
    
                if (TextUtils.isEmpty(sort)) {
                  orderBy=Programs.DEFAULT_SORT_ORDER;
                }
                else {
                  orderBy=sort;
                }
    
                Cursor c=
                    qb.query(dbhelper.getReadableDatabase(), new String[]{"_id", "name"}, selection,
                             selectionArgs, null, null, orderBy);
                c.setNotificationUri(getContext().getContentResolver(), url);
                return(c);  
        }
    

    如果您运行应用程序一次,这是有效的,但如果您多次运行它,它将继续提取和复制数据,直到您停止。我在哪里以及如何实现一个计数器,告诉它不要获取或保存或显示相同的数据集。

    由于

3 个答案:

答案 0 :(得分:0)

对象是否有ID? 该对象是否恰好具有“modified_date”或“created_date”字段?

我认为最好的方法是创建2个列表:1个列表包含服务器中的对象,1个列表包含本地数据库中的对象。然后你只需要通过ID(这应该是唯一的)和/或按日期比较两个列表。

从第一个对象列表(Web服务对象)中删除第二个列表中已有的对象,并仅保存新的对象。或者,如果您有兴趣更新本地的,请更新它们。

答案 1 :(得分:0)

更改您的数据库。添加名为已访问的新字段或默认值为 false 的字段。

当您从数据库中获取数据时,立即将该字段更新为 true

所以你的新SQL会是这样的:

SELECT * FROM TABLE1 WHERE accessed = 'false'

答案 2 :(得分:0)

我通过在本地数据库上创建查询查询来修复问题,该查询检查项是否存在并返回类似的布尔值

public boolean ProgramExists(String name) {
        db = getReadableDatabase();
        Cursor cursor = db.rawQuery("select * from " + PROGRAM_TABLE + " where " + KEY_NAME + "='" + name + "'", null);
           boolean exists = false;
           if (cursor.moveToFirst()) {
               exists = (cursor.getCount() > 0);
        }
           cursor.close();
           return exists;
        }

然后我修改了AsyncTask的onPostExecute方法,检查数据库中是否存在该项,如果是,则跳过,如果不是,则添加如下:

protected void onPostExecute(String result) {
            super.onPostExecute(result);
            ContentValues values = new ContentValues();
            try {
                JSONArray jsonArray = new JSONArray(result);
                int lenght = jsonArray.length();

                for (int i = 0; i < jsonArray.length(); i++) {
                  JSONObject jsonObject = jsonArray.getJSONObject(i);
                  String name = jsonObject.getString("name");
                  if (!dbhelper.ProgramExists(name)) {
                      values.put(Programs.NAME, name);
                      insert(Programs.CONTENT_URI, values);
                }                 
                }               
                Log.i("Data Changed", "Data changed " + lenght);
                getContext().getContentResolver().notifyChange(Programs.CONTENT_URI, null);
                } catch (JSONException e) {
                e.printStackTrace();
            }
        }

这解决了问题,并且没有更多重复的条目。