【发布时间】:2018-07-29 14:30:14
【问题描述】:
我有一个Fragment。对于片段中所有视图的OnClickListener(),我制作了另一个class UtilClickListener。我正在使用room persistence database 对spinner onItemSelected 进行数据库调用。 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);
}
}
插入数据(数据库数据库,字符串文件名);是我读取 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;
}
【问题讨论】:
-
您要更新哪个变量?
-
mGlobals.setFinalScore(scoreOfAge);我正在更新这个变量..我稍后会从片段类访问它。
-
如果你得到你的答案,你可以离开这个讨论。您在哪里向表中插入数据?
-
我在其 doInBackground 方法中的 Database Initializer 类“CRSDatabaseInitializer”中插入数据。
-
房间数据库处于 WAL 模式。直到插入数据库的数据被提交后,才能从其他线程执行其他读取操作。但是您正在使用同一线程进行插入和读取,因此在插入操作完成之前您无法读取。如果您也可以提供插入操作的代码,将会很有帮助。一个好的解决方案是将您的读取操作包装在事务中,然后仅在插入完成时执行读取。不过我会建议你使用 Rx-java。
标签: android fragment android-room