我正在使用Android Room Persistent库.我还在我的项目中实现了双向数据绑定.在项目中,我通过填写表单并在行中显示所有用户并通过单击特定用户行更新它来插入用户.以下是我的UserDao类:
@Dao
public interface UserDao {
@Query("SELECT * FROM user")
List<User> getAllUsers();
@Insert
void insertAll(User... users);
@Update
void updateUser(User... users);
@Query("SELECT * FROM user WHERE user_id IN (:userId)")
User getSpecifiedUser(int...userId);
}
Run Code Online (Sandbox Code Playgroud)
对于数据绑定,我在UserFormActivity中绑定用户模型
binding.setUserModel(userModel);
现在,由于Room持久化库不允许您在主线程中执行任何数据库操作,为了更新用户,我通过单击新线程中的行来获取用户表单中特定用户的数据,如下所示:
private void getUserFormData(final int userId) {
try {
Thread t = new Thread(new Runnable() {
public void run() {
userModel = db.userDao().getSpecifiedUser(userId);
}
}, "Thread A");
t.start();
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
在userModel中获取用户数据以进行更新之后,我希望用户数据反映在执行数据绑定的用户表单中,但它没有反映出来.我坚持这个问题.
我正在尝试使用kotlin协同程序通过此处描述的方法访问room数据库,添加插件和依赖项,并在gradle中启用kotlin协同程序.
在gradle文件中:
kotlin {
experimental {
coroutines 'enable'
}
}
dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.21" ...}
Run Code Online (Sandbox Code Playgroud)
所以我suspend为dao类中的所有方法添加了关键字,如下所示:
道类
@Query("select * from myevent")
suspend fun all(): List<MyEvent>
@Delete
suspend fun deleteEvent(event: MyEvent)
...
Run Code Online (Sandbox Code Playgroud)
并构建,然后得到这些错误
错误
e: C:\Users\projectpath\app\build\tmp\kapt3\stubs\debug\com\robyn\myapp\data\source\local\EventsDao.java:39: error: Deletion methods must either return void or return int (the number of deleted rows).
public abstract java.lang.Object deleteEventById(@org.jetbrains.annotations.NotNull()
^
e: C:\Users\projectpath\app\build\tmp\kapt3\stubs\debug\com\robyn\myapp\data\source\local\EventsDao.java:41: error: Query method parameters should either be a type that can be converted into a database column …
在主要活动中,我有LiveData,其中包含成员和单击侦听器.如果我点击一个成员,那么他的ID将通过intent.putExtra传递.该ID稍后将传递给此活动中打开的方法.通过此活动,我想查看成员的详细信息.在我的MemberInfo活动中,我标记了我的问题所在的一行.它向我显示了这个错误:无法访问主线程上的数据库,因为它可能会长时间锁定UI.
我的DAO包含以下代码:
@Query("SELECT * FROM member_table WHERE MemberID=:id")
Member getMemberInfo(long id);
Run Code Online (Sandbox Code Playgroud)
这是我的主要活动:
public class MemberMainActivity extends AppCompatActivity implements MemberListAdapter.MemberClickListener{
private MemberViewModel mMemberViewModel;
private List<Member> mMember;
void setMember(List<Member> members) {
mMember = members;
}
public static final int NEW_MEMBER_ACTIVITY_REQUEST_CODE = 1;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_member);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MemberMainActivity.this, NewMemberActivity.class);
startActivityForResult(intent, NEW_MEMBER_ACTIVITY_REQUEST_CODE);
}
});
RecyclerView recyclerView = …Run Code Online (Sandbox Code Playgroud) 我的协程正在主线程上运行,这是在我的协程上下文中指定的:
class ClickPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs), CoroutineScope, View.OnClickListener {
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main
override fun onClick(v: View?) {
when (key){
"logout" -> {
CoroutineScope(coroutineContext).launch {
CustomApplication.database?.clearAllTables()
Log.d("MapFragment", "Cleared Tables")
}
if (Profile.getCurrentProfile() != null) LoginManager.getInstance().logOut()
FirebaseAuth.getInstance().signOut()
val intent = Intent(context, MainActivity::class.java)
context.startActivity(intent)
}
}
}
Run Code Online (Sandbox Code Playgroud)
但我仍然收到此错误:
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
Run Code Online (Sandbox Code Playgroud)
在我上面对数据库的协程调用CustomApplication.database?.clearAllTables()中Room
这是我的CustomApplication: …
我有一个包含一个活动和两个片段的应用程序,在第一个片段中,我应该能够将数据插入数据库,在第二个片段中,我应该能够在 recyclerView 中看到添加的项目。
所以我制作了数据库、我的 RecyclerView 适配器和 ViewModel,
现在的问题是我应该如何管理这一切?
我应该在活动中初始化 ViewModel 并从片段中以某种方式调用它以使用插入吗?
我应该在两个片段中初始化视图模型两次吗?
我的代码如下所示:
让我们假设我在我的 Activity 中初始化了 viewholder:
class MainActivity : AppCompatActivity() {
private val articoliViewModel: ArticoliViewModel by viewModels {
ArticoliViewModelFactory((application as ArticoliApplication).repository)
}
}
Run Code Online (Sandbox Code Playgroud)
然后我的 FirstFragments 方法,我应该使用 viewModel 将数据添加到数据库中,如下所示:
class FirstFragment : Fragment() {
private val articoliViewModel: ArticoliViewModel by activityViewModels()
private fun addArticolo(barcode: String, qta: Int) { // function which add should add items on click
// here i should be able to do something like this
articoliViewModel.insert(Articolo(barcode, qta))
} …Run Code Online (Sandbox Code Playgroud)