首页 > 解决方案 > 如何在 Java 的 Room Database android 应用程序中使用 Dagger2

问题描述

我很难在我的 android 应用程序中实现 Dagger2。在我的应用程序中,我使用 RoomDB。一开始,我使用了一个 MainActivity 类,并成功实现了 RoomDB。它按方面工作。我可以从我的数据库中设置和获取值。然而,后来我决定通过将我的逻辑从 MainActivity 类移动到片段来扩展我的应用程序,其中每个片段都是相同的,只是它写入数据或从基于不同类型产品的数据库中获取数据。我试图通过实现依赖注入 Dagger2 来完成这项工作。我看过很多视频并阅读了很多关于如何做到这一点的文章,但到目前为止还没有运气。

我尝试根据文章Integrate Dagger 2 with Room Persistence Library 用几行代码实现一个示例 为了不破坏我现有的应用程序,我创建了一个与文章结构相同的新项目。在新项目中,我使用了与我的应用程序中相同的数据结构。应用程序构建成功。但是,我无法从数据库中检索我的数据,我也不知道为什么。

这是我所做的:

产品类

@Entity(tableName = "product_table")
public class Product implements Serializable {

    @PrimaryKey(autoGenerate = true)
    private int ID;

    @ColumnInfo(name = "product_count")
    private String count;
    @ColumnInfo(name = "time")
    private String time;
    @ColumnInfo(name = "p_type")
    private String product_type;

    public String getProduct_type() {
        return product_type;
    }

    public void setProduct_type(String product_type) {
        this.product_type = product_type;
    }

    public int getID() {
        return ID;
    }

    public void setID(int ID) {
        this.ID = ID;
    }

    public String getCount() {
        return count;
    }

    public void setCount(String count) {
        this.count = count;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }
}

产品道

@Dao
public interface ProductDao {

    @Insert(onConflict = REPLACE)
    void insert(Product product);
    @Delete
    void delete (Product product);
    @Delete
    void reset(List<Product> product);
    @Query("UPDATE product_table SET product_count=:sCount WHERE ID = :sID")
    void update(int sID, String sCount);
    @Query("SELECT * FROM product_table")
    List<Product> getAll();
    @Query("SELECT SUM(product_count)FROM product_table WHERE p_type = 'used' ")
    String getProductTotalCount();
    
}

应用组件

@Singleton
@Component(dependencies = {}, modules = {AppModule.class, RoomModule.class})
public interface AppComponent {

    void inject(MainActivity mainActivity);

    ProductDao productDao();

    DemoDatabase2 demoDatabase2();

    ProductRepository productRepository();

    Application application();

}

应用模块

@Module
public class AppModule {

    Application mApplication;

    public AppModule(Application application) {
        mApplication = application;
    }

    @Provides
    @Singleton
    Application providesApplication() {
        return mApplication;
    }
}

房间模块

@Module
public class RoomModule {

    private DemoDatabase2 demoDatabase2;

    public RoomModule(Application mApplication) {
        demoDatabase2 = Room.databaseBuilder(mApplication, DemoDatabase2.class, "demo-db").build();
    }

    @Singleton
    @Provides
    DemoDatabase2 providesRoomDatabase() {
        return demoDatabase2;
    }

    @Singleton
    @Provides
    ProductDao providesProductDao(DemoDatabase2 demoDatabase2) {
        return demoDatabase2.getProductDao();
    }

    @Singleton
    @Provides
    ProductRepository productRepository(ProductDao productDao) {
        return new ProductDataSource(productDao);
    }

}

演示数据库2

@Database(entities = {Product.class}, version = DemoDatabase2.VERSION, exportSchema = false)
public abstract class DemoDatabase2 extends RoomDatabase {

    static final int VERSION = 2;

    public abstract ProductDao getProductDao();

}

产品数据源

public class ProductDataSource implements ProductRepository {

    private ProductDao productDao;

    @Inject
    public ProductDataSource(ProductDao productDao) {
        this.productDao = productDao;
    }


    @Override
    public void insert(Product product) {

    }

    @Override
    public void delete(Product product) {

    }

    public String provideProductCount() {
        return productDao.getProductTotalCount();
    }

    @Override
    public List<Product> getAll() {
        return productDao.getAll();
    }
}

产品资料库

public interface ProductRepository {

    void insert(Product product);

    void delete(Product product);


    List<Product> getAll();

    String provideProductCount();
}

主要活动

public class MainActivity extends AppCompatActivity {

    @Inject
    public ProductRepository productRepository;


    TextView mTextView;
    EditText mEditText, mEditTextType;
    Button mButton;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerAppComponent.builder()
                .appModule(new AppModule(getApplication()))
                .roomModule(new RoomModule(getApplication()))
                .build()
                .inject(this);


        mTextView = findViewById(R.id.text);

        mEditTextType = findViewById(R.id.product_type); 
        mEditText = findViewById(R.id.productCount);

        mButton = findViewById(R.id.button);    


    }

    public void addValue(View view) {

       Product product = new Product();

       String count = mEditText.getText().toString();
       product.setCount(count);

       String type = mEditTextType.getText().toString();
       product.setProduct_type(type);    


        mTextView.setText(String.valueOf(product.getCount()));    


    }
}

如何从我的数据库中获取设置数据provideProductCount()?好像我尝试使用类似的东西

String producCount = productRepository.provideProductCount();

它给出的错误如下:

Caused by: java.lang.IllegalStateException: A migration from 1 to 2 was required but not found. Please provide the necessary Migration path via RoomDatabase.Builder.addMigration(Migration ...) or allow for destructive migrations via one of the RoomDatabase.Builder.fallbackToDestructiveMigration* methods.
        at androidx.room.RoomOpenHelper.onUpgrade(RoomOpenHelper.java:117)

如何解决这个问题?

标签: javaandroidandroid-roomdagger-2

解决方案


当您更改数据库时,您必须使用 fallbackToDestructiveMigration() 来允许 Room 重新创建数据库

public RoomModule(Application mApplication) {
      demoDatabase2 = Room.databaseBuilder(mApplication, DemoDatabase2.class, "demo-db")
          .fallbackToDestructiveMigration()
          .build();
    }

访问这里了解更多详情


推荐阅读