使用 retrofit2 获取数据并保存在 room

Fetching data with retrofit2 and saving in room

我正在使用 retrofit2 从服务器获取数据,然后在房间数据库中获取保存数据,然后在回收站视图中显示。但它没有显示(我的数据是我使用改造获得的)。我尝试在我的片段中显示它。在文件 ...data/data/databese/source.db 中保存了这些数据。我看到了。所以,这意味着我的代码有效。但是我不明白为什么不显示它。 我的数据库 class:

@Database(entities = {Source.class}, exportSchema = false, version = 1)
public abstract class SourceDatabase extends RoomDatabase {

    private static final String DB_NAME = "source.db";
    public abstract SourceDao sourceDao();
    private static SourceDatabase instance;

    public static SourceDatabase getInstance(Context context) {
        if (instance == null) {
            instance =buildDatabaseInstance(context);
        }
        return instance;
    }
    private static SourceDatabase buildDatabaseInstance(Context context) {
        return Room.databaseBuilder(context,
                SourceDatabase.class,
                DB_NAME).build();
    }
}

存储库:

public class DataBaseRepository {
    private static DataBaseRepository  dataBaseRepository;
    private SourceDao sourceDao;
    private LiveData<List<Source>> allSourcestoDb;
    private Context context;

    public static DataBaseRepository getInstance(Context context) {
        if (dataBaseRepository == null) {
            dataBaseRepository = new DataBaseRepository(context);
        }
        return dataBaseRepository;
    }

    public DataBaseRepository(Context context) {
        this.context = context;
        SourceDatabase db = SourceDatabase.getInstance(context);
        sourceDao = db.sourceDao();
        allSourcestoDb = sourceDao.getSources();
    }

    public void getSourceListTodb(String key) {//отправка данных в LiveData
        RestClient restClient = RestClient.getInstance();
        restClient.startRetrofit();

        restClient.getServerApi().getNews(key).enqueue(new Callback<News>() {
            @Override
            public void onResponse(Call<News> call, Response<News> response) {

                Completable.fromAction(new Action (){
                    @Override
                    public void run() throws Exception {
                        if (response.body() != null) {

                            List<Source> list = response.body().getSources();
                            sourceDao.insert(list);
                        }
                    }
                }).subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new CompletableObserver() {
                            @Override
                            public void onSubscribe(Disposable d) {

                            }

                            @Override
                            public void onComplete() {
                            }

                            @Override
                            public void onError(Throwable e) {

                            }
                        });
            }

            @Override
            public void onFailure(Call<News> call, Throwable t) {
                Log.d("error", "Can't parse data " + t);
            }
        });
    }

    public LiveData<List<Source>> getAllSourcestoDb() {
        return allSourcestoDb;
    }
}

道:

@Dao
public interface SourceDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insert(List<Source> sources);

    @Query("SELECT * FROM source")
    LiveData<List<Source>> getSources();
}

视图模型:

public class SourceViewModel extends AndroidViewModel {
    private DataBaseRepository dataBaseRepository;
    private LiveData<List<Source>> allSources; //for db

    public SourceViewModel(@NonNull Application application) {
        super(application);
        dataBaseRepository =DataBaseRepository.getInstance(application); //for db
        allSources = dataBaseRepository.getAllSourcestoDb();
    }

    public LiveData<List<Source>> getAllSources() {
        return allSources;
    }
}

和片段:

public class SavedDataFragment extends Fragment {
    private SourceViewModel sourceViewModel;
    private DataBaseRepository dataBaseRepository;
    private RecyclerView recyclerView;
    private List<Source> sourceList;
    private SavedDataAdapter adapter;

    public SavedDataFragment() {
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.saved_data,container,false);

        DataSharedPreference sharedPreference = DataSharedPreference.getSPInstance();
        String api_key = sharedPreference.loadText(getActivity());

        dataBaseRepository = new DataBaseRepository(getActivity());
        sourceViewModel = ViewModelProviders.of(this).get(SourceViewModel.class);

        recyclerView = view.findViewById(R.id.recyclerViewSavedFragment);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));

        sourceList = new ArrayList<>();

        adapter = new SavedDataAdapter(getActivity(), sourceList);
        recyclerView.setAdapter(adapter);

        sourceViewModel.getAllSources().observe(this, new Observer<List<Source>>() {
            @Override
            public void onChanged(List<Source> sources) {
              adapter.setSourceList(sourceList);
            }
        });
        dataBaseRepository.getSourceListTodb(api_key);
        return view;
    }

}

适配器:

public class SavedDataAdapter extends RecyclerView.Adapter<SavedDataAdapter.SourceSavedViewHolder> {
    private LayoutInflater inflater;
    private List<Source> sources;

    public SavedDataAdapter(Context context, List<Source> sources) {
        this.sources = sources;
        this.inflater = LayoutInflater.from(context);
    }

    @NonNull
    @Override
    public SavedDataAdapter.SourceSavedViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = inflater.inflate(R.layout.saved_item, parent, false);
        return new SourceSavedViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final SavedDataAdapter.SourceSavedViewHolder holder, int position) {
        final Source source = sources.get(position);
        holder.sourceId.setText(source.getId());
        holder.sourceName.setText(source.getName());
        holder.sourceDescription.setText(source.getDescription());
        holder.sourceURL.setText(source.getUrl());
        holder.sourceCategory.setText(source.getCategory());
        holder.sourceLanguage.setText(source.getLanguage());
        holder.sourceCountry.setText(source.getCountry());
    }

    @Override
    public int getItemCount() {
        return sources.size();
    }
    public void setSourceList(List<Source> sources) {
        this.sources = sources;
        notifyDataSetChanged();
    }

    public static class SourceSavedViewHolder extends RecyclerView.ViewHolder {
        TextView sourceName, sourceId, sourceDescription, sourceURL, sourceCategory, sourceLanguage, sourceCountry;

        public SourceSavedViewHolder(View view) {
            super(view);

            sourceName = view.findViewById(R.id.sourceName);
            sourceId = view.findViewById(R.id.sourceIdItem);
            sourceDescription = view.findViewById(R.id.sourceDescription);
            sourceURL = view.findViewById(R.id.sourceURL);
            sourceCategory = view.findViewById(R.id.sourceCategory);
            sourceLanguage = view.findViewById(R.id.sourceLanguage);
            sourceCountry = view.findViewById(R.id.sourceCountry);
        }
    }
}

尝试改变这个:

@Query("SELECT * FROM source")

收件人:

@Query("SELECT * FROM Source")

在你的 Fragment 里面 onChanged, 您正在设置 adapter.setSourceList(sourceList),其中 sourceList 是一个空数组列表。 您应该改为 setSourceList to sources,这是作为 参数传递给 onChanged 方法

的更新列表

即:-

sourceViewModel.getAllSources().observe(this, new Observer<List<Source>>() {
            @Override
            public void onChanged(List<Source> sources) {
              adapter.setSourceList(sources); // sources and not sourceList
            }
        });

还有一些事情需要注意。 对于 ex- 在您的观察方法中,您已将 this 作为第一个参数传递,这在使用 Fragments 时是错误的,因为它可能会导致内存泄漏。相反,您应该传递 viewLifeOwner.. 更多可以在此找到 link