Return 使用 AsyncTask 从 Room 自动生成的 ID 和使用 MVVM 的 onPostExecute
Return an autogenerated id from Room using AsyncTask and onPostExecute using MVVM
我正在尝试从 Room 数据库中获取自动生成的 ID,但正在努力解决如何在所有层中使用 MVVM 来实现的问题。我是 Android 编程新手。我相信 onPostExecute 是关键,但不知道如何将 id 返回到 UI.
我有这个 class:
@Entity
public class Scenario {
@PrimaryKey (autoGenerate = true)
private int id;
private String name;
public Scenario(String name) {this.name = name;}
public void setId(@NonNull int id) {this.id = id;}
@NonNull
public int getId() {return id;}
public String getName() {return name;}
}
而这个 DAO(只显示插入相关代码):
@Dao
public interface ScenarioDao {
@Insert
Long insert(Scenario scenario);
}
使用此存储库(仅显示插入相关代码):
public class ScenarioRepository {
private ScenarioDao scenarioDao;
private LiveData<List<Scenario>> allScenarios;
public ScenarioRepository(Application application) {
AppDatabase database = AppDatabase.getInstance(application);
scenarioDao = database.scenarioDao();
allScenarios = scenarioDao.getAllScenarios();
}
public void insert (Scenario scenario) {
new InsertScenarioAsyncTask(scenarioDao).execute(scenario);
}
private static class InsertScenarioAsyncTask extends AsyncTask<Scenario, Void, Long> {
private ScenarioDao scenarioDao;
private InsertScenarioAsyncTask (ScenarioDao scenarioDao) {
this.scenarioDao = scenarioDao;
}
//protected Void doInBackground(Scenario... scenarios) {
@Override
protected Long doInBackground(Scenario... scenarios) {
return scenarioDao.insert(scenarios[0]);
}
//protected void onPostExecute(Void aVoid) {
@Override
protected void onPostExecute(Long insertId) {
super.onPostExecute(insertId);
//onScenarioInserted(insertId, scenario);
}
}
}
而这个 ViewModel:
public class ScenarioDetailViewModel extends AndroidViewModel {
private ScenarioRepository repository;
public ScenarioDetailViewModel(@NonNull Application application) {
super(application);
repository = new ScenarioRepository(application);
}
public void insert(Scenario scenario) {
repository.insert(scenario);
}
}
在从按钮 OnClickListener 调用的片段中由此函数调用:
private void saveScenario() {
String name = editTextName.getText().toString();
if (name.isEmpty()) {
Toast.makeText(getActivity(), "Please enter scenario name.", Toast.LENGTH_SHORT).show();
return;
}
Scenario scenario = new Scenario(name);
scenarioDetailViewModel.insert(scenario);
}
已更新
感谢下面的评论。
public class ScenarioRepository {
private ScenarioDao scenarioDao;
private LiveData<List<Scenario>> allScenarios;
public ScenarioRepository(Application application) {
AppDatabase database = AppDatabase.getInstance(application);
scenarioDao = database.scenarioDao();
allScenarios = scenarioDao.getAllScenarios();
}
public void insert (MutableLiveData<Long> id, Scenario scenario) {
new InsertScenarioAsyncTask(scenarioDao).execute(id, scenario);
}
private static class InsertScenarioAsyncTask extends AsyncTask<Scenario, Void, Long> {
private ScenarioDao scenarioDao;
private MutableLiveData<Long> id;
private InsertScenarioAsyncTask (MutableLiveData<Long> id, ScenarioDao scenarioDao) {
this.scenarioDao = scenarioDao;
this.id=id;
}
//protected Void doInBackground(Scenario... scenarios) {
@Override
protected Long doInBackground(Scenario... scenarios) {
return scenarioDao.insert(scenarios[0]);
}
//protected void onPostExecute(Void aVoid) {
@Override
protected void onPostExecute(Long insertId) {
id.postValue(insertId);
super.onPostExecute(insertId);
}
@Override
protected void onCancelled() {
id.postValue(new Long(0));
super.onCancelled();
}
}
}
在片段中:
scenarioDetailViewModel = ViewModelProviders.of(this).get(ScenarioDetailViewModel.class);
final Observer<Long> scenarioIdObserver = new Observer<Long>() {
@Override
public void onChanged(Long aLong) {
Log.d(TAG, "onChanged, scenarioId is " + aLong);
}
};
scenarioDetailViewModel.getCurrentScenarioId().observe(getActivity(),scenarioIdObserver);
ViewModel 中的这个:
public class ScenarioDetailViewModel extends AndroidViewModel {
private static final String TAG="ScenarioDetailViewModel";
private ScenarioRepository repository;
private MutableLiveData<Long> currentId;
public ScenarioDetailViewModel(@NonNull Application application) {
super(application);
currentId = new MutableLiveData<Long>();
repository = new ScenarioRepository(application);
}
public MutableLiveData<Long> getCurrentId() {
return currentId;
}
public void insert(Scenario scenario) {
Log.d(TAG,"inserting scenario " + scenario.getName());
repository.insert(currentId,scenario);
}
public void update(Scenario scenario) {
repository.update(scenario);
}
public void delete(Scenario scenario) {
repository.delete(scenario);
}
}
您可以在 AsyncTask
中使用 LiveData
ScenarioRepository 看起来像这样:
public MutableLiveData<Long> insert (Scenario scenario) {
MutableLiveData<Long> liveData = new MutableLiveData()
new InsertScenarioAsyncTask(liveData, scenarioDao).execute(scenario);
return liveData ;
}
ِ你的 InsertScenarioAsyncTask:
private static class InsertScenarioAsyncTask extends AsyncTask<Scenario, Void, Long> {
private ScenarioDao scenarioDao;
private MutableLiveData<Long> liveData;
private InsertScenarioAsyncTask (MutableLiveData<Long> liveData, ScenarioDao scenarioDao) {
this.liveData = liveData;
this.scenarioDao = scenarioDao;
}
//protected Void doInBackground(Scenario... scenarios) {
@Override
protected Long doInBackground(Scenario... scenarios) {
return scenarioDao.insert(scenarios[0]);
}
//protected void onPostExecute(Void aVoid) {
@Override
protected void onPostExecute(Long insertId) {
liveData.postValue(insertId);
super.onPostExecute(insertId);
//onScenarioInserted(insertId, scenario);
}
@Override
protected void onCancelled() {
liveData.postValue(0);
super.onCancelled();
}
}
在你的片段中:
liveData.observe(this, insertedId -> {
// insertedId is the id of the inserted scenario
// if value is 0 then the task was cancelled
if(insertedId == 0){
}else{
}
});
我正在尝试从 Room 数据库中获取自动生成的 ID,但正在努力解决如何在所有层中使用 MVVM 来实现的问题。我是 Android 编程新手。我相信 onPostExecute 是关键,但不知道如何将 id 返回到 UI.
我有这个 class:
@Entity
public class Scenario {
@PrimaryKey (autoGenerate = true)
private int id;
private String name;
public Scenario(String name) {this.name = name;}
public void setId(@NonNull int id) {this.id = id;}
@NonNull
public int getId() {return id;}
public String getName() {return name;}
}
而这个 DAO(只显示插入相关代码):
@Dao
public interface ScenarioDao {
@Insert
Long insert(Scenario scenario);
}
使用此存储库(仅显示插入相关代码):
public class ScenarioRepository {
private ScenarioDao scenarioDao;
private LiveData<List<Scenario>> allScenarios;
public ScenarioRepository(Application application) {
AppDatabase database = AppDatabase.getInstance(application);
scenarioDao = database.scenarioDao();
allScenarios = scenarioDao.getAllScenarios();
}
public void insert (Scenario scenario) {
new InsertScenarioAsyncTask(scenarioDao).execute(scenario);
}
private static class InsertScenarioAsyncTask extends AsyncTask<Scenario, Void, Long> {
private ScenarioDao scenarioDao;
private InsertScenarioAsyncTask (ScenarioDao scenarioDao) {
this.scenarioDao = scenarioDao;
}
//protected Void doInBackground(Scenario... scenarios) {
@Override
protected Long doInBackground(Scenario... scenarios) {
return scenarioDao.insert(scenarios[0]);
}
//protected void onPostExecute(Void aVoid) {
@Override
protected void onPostExecute(Long insertId) {
super.onPostExecute(insertId);
//onScenarioInserted(insertId, scenario);
}
}
}
而这个 ViewModel:
public class ScenarioDetailViewModel extends AndroidViewModel {
private ScenarioRepository repository;
public ScenarioDetailViewModel(@NonNull Application application) {
super(application);
repository = new ScenarioRepository(application);
}
public void insert(Scenario scenario) {
repository.insert(scenario);
}
}
在从按钮 OnClickListener 调用的片段中由此函数调用:
private void saveScenario() {
String name = editTextName.getText().toString();
if (name.isEmpty()) {
Toast.makeText(getActivity(), "Please enter scenario name.", Toast.LENGTH_SHORT).show();
return;
}
Scenario scenario = new Scenario(name);
scenarioDetailViewModel.insert(scenario);
}
已更新 感谢下面的评论。
public class ScenarioRepository {
private ScenarioDao scenarioDao;
private LiveData<List<Scenario>> allScenarios;
public ScenarioRepository(Application application) {
AppDatabase database = AppDatabase.getInstance(application);
scenarioDao = database.scenarioDao();
allScenarios = scenarioDao.getAllScenarios();
}
public void insert (MutableLiveData<Long> id, Scenario scenario) {
new InsertScenarioAsyncTask(scenarioDao).execute(id, scenario);
}
private static class InsertScenarioAsyncTask extends AsyncTask<Scenario, Void, Long> {
private ScenarioDao scenarioDao;
private MutableLiveData<Long> id;
private InsertScenarioAsyncTask (MutableLiveData<Long> id, ScenarioDao scenarioDao) {
this.scenarioDao = scenarioDao;
this.id=id;
}
//protected Void doInBackground(Scenario... scenarios) {
@Override
protected Long doInBackground(Scenario... scenarios) {
return scenarioDao.insert(scenarios[0]);
}
//protected void onPostExecute(Void aVoid) {
@Override
protected void onPostExecute(Long insertId) {
id.postValue(insertId);
super.onPostExecute(insertId);
}
@Override
protected void onCancelled() {
id.postValue(new Long(0));
super.onCancelled();
}
}
}
在片段中:
scenarioDetailViewModel = ViewModelProviders.of(this).get(ScenarioDetailViewModel.class);
final Observer<Long> scenarioIdObserver = new Observer<Long>() {
@Override
public void onChanged(Long aLong) {
Log.d(TAG, "onChanged, scenarioId is " + aLong);
}
};
scenarioDetailViewModel.getCurrentScenarioId().observe(getActivity(),scenarioIdObserver);
ViewModel 中的这个:
public class ScenarioDetailViewModel extends AndroidViewModel {
private static final String TAG="ScenarioDetailViewModel";
private ScenarioRepository repository;
private MutableLiveData<Long> currentId;
public ScenarioDetailViewModel(@NonNull Application application) {
super(application);
currentId = new MutableLiveData<Long>();
repository = new ScenarioRepository(application);
}
public MutableLiveData<Long> getCurrentId() {
return currentId;
}
public void insert(Scenario scenario) {
Log.d(TAG,"inserting scenario " + scenario.getName());
repository.insert(currentId,scenario);
}
public void update(Scenario scenario) {
repository.update(scenario);
}
public void delete(Scenario scenario) {
repository.delete(scenario);
}
}
您可以在 AsyncTask
中使用 LiveData
ScenarioRepository 看起来像这样:
public MutableLiveData<Long> insert (Scenario scenario) {
MutableLiveData<Long> liveData = new MutableLiveData()
new InsertScenarioAsyncTask(liveData, scenarioDao).execute(scenario);
return liveData ;
}
ِ你的 InsertScenarioAsyncTask:
private static class InsertScenarioAsyncTask extends AsyncTask<Scenario, Void, Long> {
private ScenarioDao scenarioDao;
private MutableLiveData<Long> liveData;
private InsertScenarioAsyncTask (MutableLiveData<Long> liveData, ScenarioDao scenarioDao) {
this.liveData = liveData;
this.scenarioDao = scenarioDao;
}
//protected Void doInBackground(Scenario... scenarios) {
@Override
protected Long doInBackground(Scenario... scenarios) {
return scenarioDao.insert(scenarios[0]);
}
//protected void onPostExecute(Void aVoid) {
@Override
protected void onPostExecute(Long insertId) {
liveData.postValue(insertId);
super.onPostExecute(insertId);
//onScenarioInserted(insertId, scenario);
}
@Override
protected void onCancelled() {
liveData.postValue(0);
super.onCancelled();
}
}
在你的片段中:
liveData.observe(this, insertedId -> {
// insertedId is the id of the inserted scenario
// if value is 0 then the task was cancelled
if(insertedId == 0){
}else{
}
});