我有一个Fragment
。对于片段中所有视图中的OnClickListener()
,我创建了另一个class UtilClickListener
。我正在使用spinner
在onItemSelected
room persistence database
上进行数据库调用。 database
调用首先将数据插入表中,然后在我的应用程序中更新应用程序变量。
因此,我正在尝试在数据库调用之后访问spinner
onItemSelected()
上的更新的应用程序变量。但是变量不会立即更新,稍后当我单击fragment
的其他视图时,我会获得更新的值。
Fragment
代码:
public class Calculator extends Fragment {
@Nullable
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Spinner ageSpinner = rootView.findViewById(R.id.spinner_how_old);
ageSpinner.setOnItemSelectedListener(new UtilOnClickListener(this));
CRSCalculatorAdapter ageListAdapter = new CRSCalculatorAdapter(rootView.getContext(),
android.R.layout.simple_spinner_item,Arrays.asList(rootView.getContext().getResources().getStringArray(R.array.age_group)) );
ageSpinner.setAdapter(ageListAdapter);
}
}
UtilOnClickListener类代码:
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
switch (parentSpinnerId[1]) {
case "spinner_how_old}":
mGlobals.setAge(parent.getSelectedItem().toString());
CRSDatabaseInitializer.populateAsync(CRSDatabase.getDatabase(view.getContext()), crsCalculator.getContext(), Constants.QUERY_TYPE_ALL);
mListener.onChangeActionBarTitle(Integer.valueOf(mGlobals.getFinalScore())); // Here I am updating score in the action bar which is updating late on the next view click
break;
}
“ CRSDatabaseInitializer”正在为数据库调用调用Asynctask。
这是数据库初始化程序代码:
public class CRSDatabaseInitializer {
public static void populateAsync(@NonNull final CRSDatabase db, Context context, String typeOfQuery) {
PopulateDbAsync task = new PopulateDbAsync(db, typeOfQuery);
}
private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {
private final CRSDatabase mDb;
private final String mQueryType;
PopulateDbAsync(CRSDatabase db, String queryType) {
mDb = db;
mQueryType = queryType;
}
@Override
protected Void doInBackground(final Void... params) {
int scoreOfAge = Integer.valueOf(getScoreOnAge(mDb));
mGlobals.setFinalScore(scoreOfAge); // this is the application variable I need to update.
return null;
}
public static int getScoreOnAge(CRSDatabase db) {
int userScore = 0;
if (mGlobals.getAge() != null) {
userScore = Integer.valueOf(db.ageScoreDao().getScore(mGlobals.getAge(), mGlobals.getMarriedOrNot()));
}
return userScore;
}
}
从CRSDatabaseInitializer添加更多代码,将数据插入会议室数据库中
private static void insertNocCode(CRSDatabase db) {
NocCode nocData = new NocCode();
List<String[]> str = insertData(db, "nocCodes.csv");
for (int i = 0; i < str.size(); i++) {
nocData.setmNocCode(str.get(i)[0]);
nocData.setmTitle(str.get(i)[1]);
nocData.setmSkilltype(str.get(i)[2]);
addCRSData(db, nocData);
}
}
insertData(数据库db,字符串文件名);是我读取csv文件并在csv文件中插入所有列的方法。
public static List<String[]> insertData(CRSDatabase db, String fileName) {
String[] str = new String[5];
ArrayList<String[]> stringArray = new ArrayList<>();
try {
InputStreamReader is = new InputStreamReader(mContext.getAssets()
.open(fileName));
BufferedReader reader = new BufferedReader(is);
String line = "";
while ((line = reader.readLine()) != null) {
str = line.split(",");
stringArray.add(str);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally
{
}
return stringArray;
}
以及插入方法定义:
private static NocCode addCRSData(final CRSDatabase db, NocCode nocCode) {
db.nocCodeDao().insert(nocCode);
return nocCode;
}
答案 0 :(得分:0)
因此,这是我正在解决的此问题的更新。我使用处理程序解决了这个问题。在进行数据库调用时,我先让DB更新变量,然后运行一个处理程序以在片段中稍后获取更新的值。 这是我在UtilOnClickListener类中更新的代码。
private static class MyHandler extends Handler {}
private final MyHandler mHandler = new MyHandler();
public static class UtilRunner implements Runnable {
private final WeakReference<Calculator> mActivity;
public UtilRunner(Calculator activity) {
mActivity = new WeakReference<Calculator>(activity);
}
@Override
public void run() {
Calculator activity = mActivity.get();
if (activity.getContext() instanceof MainActivity) {
OnActionBarListener mListener = (OnActionBarListener) activity.getContext();
Globals mGlobals = (Globals) activity.getActivity().getApplicationContext();
mListener.onChangeActionBarTitle(mGlobals.getFinalScore());
}
}
}
我正在从视图的OnClick运行处理程序:
mHandler.postDelayed(mRunnable, 200);
答案 1 :(得分:0)
有多种处理方法。在您的情况下,即使您从同一线程进行插入和读取,我也无法理解为什么在提交插入数据之前会执行读取操作。您可以看一下这个讨论:stackOverFlow,我从这次讨论中学到的是,掌握控制权总是更好,因为数据库内部实现可能会不时发生变化。让我们来看看这个表情:
通过使用Dao类中的注解@Transaction或将要插入的代码包装在db.beginTransaction和db.endTransaction。devGuide中,将读取的查询包装在事务中。这样可以确保在写入数据库时不会发生读取。
为此,我发现最好的是使用Rx-Java See Introdution。您可以进行插入,然后在插入完成时得到通知并执行读取操作。由于插入操作不会返回任何内容,因此请将其包装在Completable.fromAction中。可观察到的可观察变量具有运算符 obs1.andThen(obs2),从名称中首先可以看出obs1已完成,然后仅执行了obs2。请注意,您的db.ageScoreDao()。getScore(..)方法应返回一个observable,因此将返回值包装在Observable中;
Completable.fromAction(new Action(){
@Override
public void run() throws Exception {
db.nocCodeDao().insert(nocCode);
}
}).andThen(return db.ageScoreDao().getScore(..)
.subscribeOn(Scheduler.io()) //do database query on io thread
.observeOn(AndroidScheduler.mainThread())
.subscribeWith(new DisposableObserver<Object>(){
@Override
public void onNext(Object o) {
//Here you update the variable
}
@Override
public void onError(Throwable e) {..}
@Override
public void onComplete() {..}
});