问题描述
所以我正在关注 MVVM 架构,在那里我有一个包含银行交易的数据库:
@Database(entities = {Transaction.class},version = 1,exportSchema = false) @TypeConverters({DateConverter.class})
public abstract class TransactionsRoomDatabase extends RoomDatabase {
public abstract TransactionDao transactionDao();
private static volatile TransactionsRoomDatabase INSTANCE;
private static final int NUMBER_OF_THREADS = 4;
private static final ExecutorService databaseWriteExecutor =
Executors.newFixedThreadPool(NUMBER_OF_THREADS);
public static ExecutorService getDatabaseWriteExecutor() {
return databaseWriteExecutor;
}
public static TransactionsRoomDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (TransactionsRoomDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),TransactionsRoomDatabase .class,"database")
.build();
}
}
}
return INSTANCE;
} }
我的 Dao 类有 2 个查询:
@Dao
public interface TransactionDao {
// first query
@Query("SELECT * " +
"FROM transactions_table " +
"ORDER BY bookingDate,valueDate DESC")
LiveData<List<Transaction>> getAllTransactions();
// second query that I don't kNow how to call it in my fragment
@Query("SELECT * " +
"FROM transactions_table " +
"WHERE debtorAccount = :debtorAccount " +
"ORDER BY valueDate DESC "
)
LiveData<List<Transaction>> getTransactionsFiltered(String debtorAccount);
// insert the list of transactions in databse
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertTransactions(List<Transaction> transactionList);
}
存储库:
public class TransactionRepository {
private TransactionDao transactionDao;
private LiveData<List<Transaction>> transactionList;
public TransactionRepository(Application application) {
TransactionsRoomDatabase roomDatabase = TransactionsRoomDatabase.getDatabase(application);
transactionDao = transactionsRoomDatabase.transactionDao();
transactionList = transactionDao.getAllTransactions();
}
// get all transactons
public LiveData<List<Transaction>> getAllTransactions() {
return transactionList;
}
// insert transactions in database using DAO. Are done in another thread so the main thread is not blocked
public void insertTransactions(List<Transaction> transactionList) {
TransactionsRoomDatabase.getDatabaseWriteExecutor().execute(() -> transactionDao.insertTransactions(transactionList));
}
}
视图模型:
public class HomeAdvancedviewmodel extends Androidviewmodel {
private TransactionRepository transactionRepository;
private LiveData<List<Transaction>> allTransactions;
public HomeAdvancedviewmodel(Application application) {
super(application);
transactionRepository = new TransactionRepository(application);
allTransactions = transactionRepository.getAllTransactions();
}
public LiveData<List<Transaction>> getAllTransactions() {
return allTransactions;
}
}
在主要片段中,我用数据库中的所有事务填充了一个 recyclerView:
public class MainFragment extends Fragment {
private HomeAdvancedviewmodel homeAdvancedviewmodel;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
homeAdvancedviewmodel = new viewmodelProvider(this).get(HomeAdvancedviewmodel.class); // define viewmodel
}
@Override
public void onViewCreated(@NonNull View view,@Nullable Bundle savedInstanceState) {
super.onViewCreated(view,savedInstanceState);
/* Here I'm using the observable pattern. When transactions in database are changed,I call my setCurrentTransactions(...) function that populates again the recycler view */
homeAdvancedviewmodel.getAllTransactions().observe(getViewLifecycleOwner(),transactions -> setCurrentTransactions(transactionlistadapter,recyclerViewTransactions,transactions));
}
}
getTransactionsFiltered(String debtorAccount)
填充SAME recyclerView(按下某个按钮时)?我不能有类似的东西
public void getTransactionsFiltered(String account) {
TransactionsRoomDatabase.getDatabaseWriteExecutor().execute(() -> transactionDao.getTransactionsFiltered(account)); // calling the 2nd query in DAO
}
在我的 DAO 中,因为查询应该在另一个线程上完成(我不允许在主线程上执行),所以我的 DAO 无法返回事务列表。
你能提供任何帮助吗?
解决方法
答案
我是这样解决的:
在 Repository 类中添加了以下功能:
public class TransactionRepository {
private TransactionDao transactionDao;
private LiveData<List<Transaction>> transactionList;
public TransactionRepository(Application application) {
TransactionsRoomDatabase roomDatabase = TransactionsRoomDatabase.getDatabase(application);
transactionDao = transactionsRoomDatabase.transactionDao();
transactionList = transactionDao.getAllTransactions();
}
// get all transactons
public LiveData<List<Transaction>> getAllTransactions() {
return transactionList;
}
// NEW FUNCTION ADDED
public LiveData<List<Transaction>> getTransactionsFiltered(String account) {
return accountsRoomDatabase.transactionDao().getTransactionsFiltered(account);
}
}
这样做,主线程不会被阻塞。不确定这是否是最好的方法,但它解决了我的问题