개조 2로 데이터 가져 오기 및 방에 저장

Nov 16 2020

서버에서 데이터를 가져오고 방 데이터베이스에 데이터를 저장 한 다음 리사이클 러보기에 표시하기 위해 retrofit2를 사용하고 있습니다. 그러나 그것은 표시되지 않습니다 (개장을 사용하여 얻은 데이터). 내 조각에 표시하려고합니다. ... data / data / databese / source.db 파일에 이러한 데이터가 저장됩니다. 나는 그것을 참조. 그래서 그것은 내 코드가 작동한다는 것을 의미합니다. 하지만 왜 표시되지 않는지 이해할 수 없습니다. 내 데이터베이스 클래스 :

@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 :

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

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

viewModel :

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

답변

1 DebarshiBhattacharjee Nov 16 2020 at 20:08

onChanged 내부 의 Fragmentadapter.setSourceList(sourceList) 에서 sourceList 가 빈 arrayList 인 위치를 설정 하고 있습니다. 대신 onChanged 메소드에 인수로setSourceList to sources 전달 된 업데이트 된 목록 이어야합니다.

그건 :-

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

또한 처리해야 할 사항이 몇 가지 더 있습니다. 예를 들어, Observation 메서드에서 메모리 누수를 일으킬 수 있으므로 Fragments 를 사용할 때 잘못된 첫 번째 인수로 이것을 전달 했습니다. 대신 viewLifeOwner ..를 전달해야합니다 . 자세한 내용은이 링크에서 찾을 수 있습니다. ViewLifecycleOwner를 LifecycleOwner로 사용합니다.

lolloCreator Nov 16 2020 at 14:09

이것을 변경하십시오.

@Query("SELECT * FROM source")

에:

@Query("SELECT * FROM Source")