如何解决通过使用 MVVM 架构的 Room 从远程服务器获取数据并使其在本地数据库中可用来实现缓存
大家好,我对使用 MVVM 设计模式的 Android 架构仍然很陌生,所以我已经设法创建了实现,但我需要一些帮助来检查实现是否正确并增强了 MVVM 的全部功能:>
- 我认为我在片段中使用 Context 然后通过 ViewModel 和 Repository 引用它失败了。我犯了那个错误是否正确,如果是,为了保持单一来源的真相原则,执行它的最佳方法是什么。
请花点时间查看以下代码:提前感谢您的帮助::
NotificationsFragment 类
package com.okellosoftwarez.popularmovies.ui.notifications;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.room.Room;
import com.okellosoftwarez.popularmovies.R;
import com.okellosoftwarez.popularmovies.ui.model.results;
import java.util.List;
public class NotificationsFragment extends Fragment {
private NotificationsViewModel notificationsViewModel;
private RecyclerView movieRecyclerView;
private MovieAdapter movieAdapter;
private List<com.okellosoftwarez.popularmovies.ui.model.results> results;
private RecyclerView.LayoutManager movieLayoutManager;
private String TAG = "NotFrag";
private MovieDB movieDB;
public View onCreateView(@NonNull LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
notificationsViewModel =
ViewModelProviders.of(this).get(NotificationsViewModel.class);
View root = inflater.inflate(R.layout.fragment_notifications,container,false);
movieRecyclerView = root.findViewById(R.id.popularMovieRecycler);
movieRecyclerView.setHasFixedSize(true);
movieLayoutManager = new LinearLayoutManager(getActivity());
movieRecyclerView.setLayoutManager(movieLayoutManager);
movieRecyclerView.setItemAnimator(new DefaultItemAnimator());
movieDB = Room.databaseBuilder(getActivity(),MovieDB.class,"Movies_db").fallbackToDestructiveMigration().build();
if (isNetworkConnected(getActivity())){
notificationsViewModel.getMovie_listFromRemoteDB(getActivity());
Log.d(TAG,"onCreateView: isNetConnected");
}
else {
Toast.makeText(getActivity(),"No Internet Found Displaying Cached Data...",Toast.LENGTH_SHORT).show();
}
notificationsViewModel.getMovie_listFromLocalDB(getActivity()).observe(getViewLifecycleOwner(),new Observer<List<results>>() {
@Override
public void onChanged(List<results> results) {
Log.d(TAG,"onChanged: LocalDB");
movieAdapter = new MovieAdapter(getActivity(),results);
movieRecyclerView.setAdapter(movieAdapter);
}
});
return root;
}
private boolean isNetworkConnected(Context context){
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}
}
NotificationsViewModel 类
package com.okellosoftwarez.popularmovies.ui.notifications;
import android.content.Context;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModel;
import com.okellosoftwarez.popularmovies.ui.model.results;
import java.util.List;
public class NotificationsViewModel extends ViewModel {
private static final String TAG = "NotificationVmodel";
String moviesKey = "27dada59165b58ea926aae10fb0ea263";
private LiveData<List<results>> movie_list;
private MovieRepository movieRepository = MovieRepository.getRepositoryInstance();
public LiveData<List<results>> getMovie_listFromRemoteDB(Context context){
movie_list = movieRepository.getMoviesFromRemote(context);
return movie_list;
}
public LiveData<List<results>> getMovie_listFromLocalDB(Context context) {
movie_list = movieRepository.getMoviesFromDB(context);
return movie_list;
}
}
MovieRepository 类
package com.okellosoftwarez.popularmovies.ui.notifications;
import android.content.Context;
import android.util.Log;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Transformations;
import com.okellosoftwarez.popularmovies.ui.model.Movie;
import com.okellosoftwarez.popularmovies.ui.model.detail;
import com.okellosoftwarez.popularmovies.ui.model.results;
import org.jetbrains.annotations.Contract;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MovieRepository {
private MutableLiveData<List<results>> movieList;
public static final MovieRepository repositoryInstance = new MovieRepository();
private static final String TAG = "MoviesRepo";
public static MovieRepository getRepositoryInstance() {
return repositoryInstance;
}
public LiveData<List<results>> getMoviesFromDB(Context context) {
return DatabaseInstance.getDatabaseInstance(context).movieDAO().retrieveAll();
}
public LiveData<List<results>> getMoviesFromRemote(Context context) {
if (movieList == null) {
movieList = new MutableLiveData<>();
loadMovies(context);
}
return movieList;
}
private void loadMovies(Context context) {
Call<detail> detailCall = MovieRetrofitClient.getInstance().getMovieInterface().getMoviesPerPage();
detailCall.enqueue(new Callback<detail>() {
@Override
public void onResponse(Call<detail> call,Response<detail> response) {
if (response != null && response.isSuccessful()) {
movieList.setValue(response.body().getResultsList());
Log.d(TAG,"onResponse: " + response.body().getResultsList().size());
// Worker Thread
Thread databaseThread = new Thread() {
@Override
public void run() {
super.run();
DatabaseInstance.getDatabaseInstance(context).movieDAO().deleteAllMovies();
DatabaseInstance.getDatabaseInstance(context).movieDAO().insertMovie(response.body().getResultsList());
}
};
databaseThread.start();
} else {
movieList.setValue(null);
Log.d(TAG,"onResponse: Something Happened");
}
}
@Override
public void onFailure(Call<detail> call,Throwable t) {
Log.d(TAG,"onFailure: Totally Failure...");
}
});
}
}
数据库实例类
package com.okellosoftwarez.popularmovies.ui.notifications;
import android.content.Context;
import androidx.room.Room;
public class DatabaseInstance {
public static MovieDB databaseInstance ;
public static MovieDB getDatabaseInstance(Context context) {
databaseInstance = Room.databaseBuilder(context,"Movies_db").fallbackToDestructiveMigration().build();
return databaseInstance;
}
}
MovieDao 类
package com.okellosoftwarez.popularmovies.ui.notifications;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import com.okellosoftwarez.popularmovies.ui.model.results;
import java.util.List;
@Dao
public interface MovieDAO {
@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertMovie(List<results> movieList );
@Query("SELECT * FROM Movies")
public LiveData<List<results>> retrieveAll();
@Query("DELETE FROM Movies")
public void deleteAllMovies();
}
MovieDB 类
package com.okellosoftwarez.popularmovies.ui.notifications;
import androidx.room.Database;
import androidx.room.RoomDatabase;
import com.okellosoftwarez.popularmovies.ui.model.Movie;
import com.okellosoftwarez.popularmovies.ui.model.results;
@Database(entities = {results.class},version = 1,exportSchema = false)
public abstract class MovieDB extends RoomDatabase {
public abstract MovieDAO movieDAO();
}
MovieInterface 类
package com.okellosoftwarez.popularmovies.ui.notifications;
import com.okellosoftwarez.popularmovies.ui.model.detail;
import com.okellosoftwarez.popularmovies.ui.model.results;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.GET;
public interface MovieInterface {
String BASE_URL = "https://api.themoviedb.org/3/movie/";
@GET("popular?api_key=27dada59165b58ea926aae10fb0ea263&language=en-US&page=1")
Call<detail> getMoviesPerPage();
}
数据库实例类
package com.okellosoftwarez.popularmovies.ui.notifications;
import android.content.Context;
import androidx.room.Room;
public class DatabaseInstance {
public static MovieDB databaseInstance ;
public static MovieDB getDatabaseInstance(Context context) {
databaseInstance = Room.databaseBuilder(context,"Movies_db").fallbackToDestructiveMigration().build();
return databaseInstance;
}
}
链接到 Github 存储库以获取更多信息:https://github.com/okelloEnos/Popular-Movies
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。