我应该在哪些情况下使用Android上的SQLite来缓存数据?

时间:2015-06-19 14:06:49

标签: android performance sqlite caching

所以,我为视频平台写了一个客户端。

让我们看看我的应用的一个功能: 获取视频
现在,我使用 RxJava + Retrofit 来获取视频并进行显示。
以下是代码没有缓存
改造api

@GET("/api_v3/?service=media&action=list&pager%3AobjectType=KalturaFilterPager&pager%3ApageSize=500&pager:pageIndex=1")
    Observable<KalturaVideoResponse> getVideoListObservable();

在Activity 中的用法:

API.getVideoListObservable()
                .doOnError(t -> t.printStackTrace())  //handle error
                .map(r -> r.getObjects())  //get business objects from response
                .doOnNext(l -> VideoActivity.this.runOnUiThread(() -> fragment.updateVideoList(l)))  //update UI
                .doOnNext(l -> kalturaVideoList.addAll(l))  //save objects into memory
                .subscribeOn(Schedulers.io())  //do it in background thread
                .observeOn(AndroidSchedulers.mainThread())  //handle result in UI thread
                .subscribe();

优点:

  • 非常简单的代码
  • 简单处理例外情况
  • 简单的数据操作(使用RxJava运算符)

缺点:

  • 每次旋转都会有新的HttpRequest
  • 许多匿名课程
  • 如果我经常这样做,我会在顶级设备上获得OOM。例如,在阿尔卡特一触摸4033d

等例子。使用 SyncAdapter + ContentProvider 。 我不会添加SyncAdapter配置代码,我只需添加代码,负责视频同步

private void updateVideoList(){
        KalturaVideoResponse videoList = API.getVideoList();
        getContext().getContentResolver().delete(KalturaVideoColumns.CONTENT_URI, null, null);
        for(KalturaVideo video : videoList.getObjects()){
            final KalturaVideoContentValues values = new KalturaVideoContentValues();
            values
                    .putCategories(video.getCategories())
                    .putCategoriesIds(video.getCategoriesIds())
                    .putDataUrl(video.getDataUrl())
                    .putDescription(video.getDescription())
                    .putName(video.getName())
                    .putDownloadUrl(video.getDownloadUrl())
                    .putDuration(video.getDuration())
                    .putKalturaId(video.getId())
                    .putThumbnailUrl(video.getThumbnailUrl());

            getContext().getContentResolver().insert(KalturaVideoColumns.CONTENT_URI, values.values());
        }
    }   getContext().getContentResolver().insert(KalturaVideoColumns.CONTENT_URI, values.values());
        }
    }

每次syncadapter同步时都会调用此函数。在我的配置中,它每30分钟完成一次。

在活动中获取数据(使用CursorLoader):

@Override
    public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
        final String sortOrder = KalturaVideoColumns._ID + " DESC";
        return new CursorLoader(
                getActivity().getApplicationContext(),
                KalturaVideoColumns.CONTENT_URI,
                null,
                null,
                null,
                sortOrder);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        KalturaVideoCursor videoCursor = new KalturaVideoCursor(cursor);
        if(videoCursor.moveToFirst()){
            videoAdapter = new VideoAdapter(getActivity(), cursor, true);
            viewHolder.videoList.setAdapter(videoAdapter);
            viewHolder.videoList.setOnItemClickListener(onItemClickListener);
        }
    }

在此代码中,我只是提取视频,这些视频由SyncAdapter缓存并使用VideoAdapter显示。

优点:

  • 我没有很多HttpRequests,我每隔30分钟就做一次。
  • 简单活动生命周期处理
  • 非常快速地加载和显示数据

缺点:

有2个致命的劣势。

  • 如果视频被编辑或删除,我不知道。

  • 如果我经常同步(例如每3分钟),我的应用程序运行速度非常慢......

如何解决此问题?

当我开始学习android时,我在Udacity上找到了非常漂亮的android课程。在这个课程中,我开发了Sunshine app。在这个应用程序中使用了syncadapter,它在SQLite中缓存了数据。在Sunshine app中有关于天气的数据,这些数据不经常更新 但是如果发生了变化,我需要经常同步才能看到。 我是否需要改进缓存/同步代码,或者每次需要数据时都应该请求?

0 个答案:

没有答案