在主要活动中,我有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 = findViewById(R.id.recyclerviewcard_member);
final MemberListAdapter adapter = new MemberListAdapter(this);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mMemberViewModel = ViewModelProviders.of(this).get(MemberViewModel.class);
mMemberViewModel.getAllMember().observe(this, new Observer<List<Member>>() {
@Override
public void onChanged(@Nullable final List<Member> members) {
mMember = members;
// Update the cached copy of the words in the adapter.
adapter.setMember(members);
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == NEW_MEMBER_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
Member member = new Member(data.getStringExtra(NewMemberActivity.EXTRA_REPLY), data.getStringExtra(NewMemberActivity.EXTRA_REPLY2));
mMemberViewModel.insert(member);
} else {
Toast.makeText(
getApplicationContext(),
R.string.empty_not_saved,
Toast.LENGTH_LONG).show();
}
}
public void onMemberClick(int position) {
Member member = mMember.get(position);
Intent intent = new Intent(getApplicationContext(),MemberInfo.class);
intent.putExtra("MemberID", member.getId());
MemberInfo.open(this, member.getId());
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的活动:
public class MemberInfo extends AppCompatActivity {
public static void open(Activity activity, long memberid) {
Intent intent = new Intent(activity, MemberInfo.class);
intent.putExtra("MemberID", memberid);
activity.startActivity(intent);
}
private List<Member> mMember;
private MemberViewModel mMemberViewModel;
void setMember(List<Member> members){
mMember = members;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_memberinfo);
Log.i("okay", "memberinfo");
Intent intent = getIntent();
if (intent != null && intent.hasExtra("MemberID")) {
long memberid = intent.getLongExtra("MemberID", -1);
// TODO: get customer details based on customer id
TextView firstname = findViewById(R.id.layout_memberfirstname);
TextView surname = findViewById(R.id.layout_membersurname);
TextView balance = findViewById(R.id.layout_memberbalance);
-------------Member member = MemberRoomDatabase.getDatabase().memberDao().getMemberInfo(memberid);-------------
firstname.setText(member.getFirstname());
surname.setText(member.getSurname());
}
else {
Toast.makeText(
getApplicationContext(),
R.string.empty_not_saved,
Toast.LENGTH_LONG).show();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想也许是因为我错过了一个AsyncTask方法.我试过这个,但这也行不通:
private static class insertMemberInfoAsyncTask extends AsyncTask<Member, Void, Void> {
private MemberDao mAsyncTaskDao;
insertMemberInfoAsyncTask(MemberDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(Member... params) {
Member member = params[0];
mAsyncTaskDao.getMemberInfo(member.getId());
return null;
}
}
public Member getMemberInfo(long id) {
mAllMember = mMemberDao.getAllMember();
Member member = mMemberDao.getMemberInfo(id);
new insertMemberInfoAsyncTask(mMemberDao).execute(member);
return member;
}
Run Code Online (Sandbox Code Playgroud)
我想我用的方法不对.有谁能够帮我?
就我而言,如果您在使用协程时添加 Dispatcher.IO,它就会起作用:
viewModelScope.launch(Dispatchers.IO) {
//your database call
}
Run Code Online (Sandbox Code Playgroud)
一种选择是将您的查询更新为:
@Query("SELECT * FROM member_table WHERE MemberID=:id")
LiveData<Member> getMemberInfo(long id);
Run Code Online (Sandbox Code Playgroud)
(或类似的,使用Flowable).这样就无需手动创建自己的AsyncTask.
返回类型LiveData周围的包装器会Member自动向Room发出信号,表明查询可以/应该异步执行.按https://developer.android.com/training/data-storage/room/accessing-data(我的重点):
注意:除非您调用
allowMainThreadQueries()构建器,否则Room不支持主线程上的数据库访问,因为它可能会长时间锁定UI.异步查询 - 返回LiveData或Flowable实例的查询 - 不受此规则的约束,因为它们在需要时在后台线程上异步运行查询.
您可以使用Future和Callable。因此,您无需编写冗长的asynctask即可执行查询而无需添加allowMainThreadQueries()或使用LiveData。
我的道查询:-
@Query("SELECT * from user_data_table where SNO = 1")
UserData getDefaultData();
Run Code Online (Sandbox Code Playgroud)
我的存储库方法:-
public UserData getDefaultData() throws ExecutionException, InterruptedException {
Callable<UserData> callable = new Callable<UserData>() {
@Override
public UserData call() throws Exception {
return userDao.getDefaultData();
}
};
Future<UserData> future = Executors.newSingleThreadExecutor().submit(callable);
return future.get();
}
Run Code Online (Sandbox Code Playgroud)
小智 5
对我来说allowMainThreadQueries()有效。
这允许有空间支持主线程上的数据库访问。
看下面的代码
@Database(entities = [Word::class ],version = 1)
abstract class VocabularyDatabase:RoomDatabase() {
companion object {
private lateinit var INSTANCE:VocabularyDatabase
fun getInstance(context:Context):VocabularyDatabase= Room.databaseBuilder(
context,
VocabularyDatabase::class.java,
"vocabulary"
)
.createFromAsset("vocabulary.db")
.allowMainThreadQueries()
.build()
}
abstract fun dao():WordDao
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9022 次 |
| 最近记录: |