【问题标题】:Combine Room and Retroffit with Dagger2将房间和改造与 Dagger2 结合起来
【发布时间】:2018-07-02 14:07:43
【问题描述】:

使用 Room 和 Retrofit 创建 DAO 的正确方法是什么?

我有这样的数据库模块:

@Module
public class ApplicationDatabaseModule {

private final String mDatabaseName;
ApplicationDatabase mApplicationDatabase;

public ApplicationDatabaseModule(@ApplicationContext Context context, Class<? extends ApplicationDatabase> roomDataBaseClass, String databaseName) {
    mDatabaseName = databaseName;
    mApplicationDatabase = Room.databaseBuilder(context, roomDataBaseClass, mDatabaseName).build();
}

@Singleton
@Provides
ApplicationDatabase provideApplicationDatabase() {
    return mApplicationDatabase;
}

@Singleton
@Provides
CitiesDao provideCitiesDao() {
    return mApplicationDatabase.getCitiesDao();
}

}

POJO 类是这样的:

@Entity
public class City {

@PrimaryKey
@ColumnInfo(name = "id")
private int cityId;

@ColumnInfo(name = "name")
private String cityName;

public int getCityId() {
    return cityId;
}

public void setCityId(int cityId) {
    this.cityId = cityId;
}

public String getCityName() {
    return cityName;
}

public void setCityName(String cityName) {
    this.cityName = cityName;
}

@Override
public String toString() {
    return "City [cityId = " + cityId + ", cityName = " + cityName + "]";
}
}

DAO 界面如下:

@Dao
public interface CitiesDao {

@Insert
void insertCities(City... cities);

@Query("SELECT * FROM City")
City[] queryCities();

}

以及用于改造的 API:

public interface CitiesApi {
@GET("/api/cities")
Call<City[]> requestCities();
}

据我所知,DAO 负责访问数据,包括通过 REST 客户端传递的数据。但这两个部分由接口表示并内置在单独的类中。实现 DAO 的正确方法是什么?

【问题讨论】:

标签: android retrofit2 dao dagger-2 android-room


【解决方案1】:

DAO 负责访问数据

是的

,包括通过 REST-client 传递的数据。

天哪

实现 DAO 的正确方法是什么?

Room 已经根据您的接口 + 注释为您的 DAO 生成了正确的实现方式,我认为它称为 CitiesDao_Impl

使用 Room 和 Retrofit 创建 DAO 的正确方法是什么?

Room 不知道 Retrofit,也不应该知道 Retrofit。它只关心本地数据持久性。

意味着您的 DAO 需要如下所示:

@Dao
public interface CitiesDao {

    @Insert
    @Transaction
    void insertCities(City... cities);

    @Query("SELECT * FROM City")
    LiveData<List<City>> queryCities();

}

所以你实际上需要的是一个 Worker,它会在缓存无效(强制获取新数据)或同步任务应该运行时(例如设备正在充电时)在后台获取新数据你在 WIFI 上,你是在凌晨 2 点到 7 点——为此你需要WorkManager)。

虽然立即获取新数据相当容易,但您只需要在单例上下文中从 doInBackground 返回 null 的 AsyncTask,或者将后台任务发布到您自己的 Executor。

 public class FetchCityTask extends AsyncTask<Void, Void, Void> {
     ...

     @Override
     protected Void doInBackground(Void... params) {
         List<City> cities = citiesApi.requestCities().execute().body(); // TODO error handling
         citiesDao.insertCities(cities);
         return null;
     }
 }

然后

new FetchCityTask(...).execute();

现在,当此任务运行时,您的 UI 将通过观察您存储在 ViewModel 中的 LiveData 更新为最新数据。

public class CitiesViewModel
        extends ViewModel {
    private final CitiesDao citiesDao;

    private LiveData<List<City>> liveResults;

    public CitiesViewModel(...) {
        ...
        liveResults = citiesDao.queryCities();
    }

    public LiveData<List<City>> getCities() {
        return liveResults;
    }
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    recyclerView = view.findViewById(R.id.recycler_view);
    CitiesViewModel viewModel = ViewModelProviders.of(this).get(CitiesViewModel.class, ...);

    ...
    viewModel.getTasks().observe(getViewLifecycle(), list -> {
        //noinspection Convert2MethodRef
        listAdapter.submitList(list);
    });
}

【讨论】:

  • 如何将WorkManager导入项目? import androidx.work.WorkManager; 找不到 work 包。
【解决方案2】:

您想创建一个存储库类来处理您的数据。然后,您只需与您的存储库进行交互。给你一些伪代码:

class Repository {
   private CitiesDao localSource;
   private CitiesApi remoteSource;

   public Repository() {
       //initialize objects here
   }

   City[] getCities() {
       if (networkIsAvailable) {
           City[] cities = remoteSource.requestCities();
           saveCitiesToDatabase(cities);
           return cities;
       } else {
           return localSource.queryCities();
       }
   }

   private void saveCitiesToDatabase(City[] cities) {
    //TODO save cities to databse
   }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-16
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    • 2019-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多