我需要向我的 SQLiteDatabase 添加一行,因此我想获得新创建的行 ID。我扩展了 AsyncTask 类以便在后台线程中运行这个任务,这里是:
private class InsertLangTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
try {
if (mDB.isOpen()) {
try {
mId = mDB.insertOrThrow(DBS.D.TN, null, mCV);
}
catch (SQLException e) {
StringBuilder query = new StringBuilder();
query.append("SELECT " + BaseColumns._ID + " FROM " + DBS.D.TN + " WHERE ");
Object[] bindArgs = new Object[mCV.size()];
int i = 0;
for (Map.Entry<String, Object> entry: mCV.valueSet()) {
query.append((i > 0) ? " AND " : "");
query.append(entry.getKey());
query.append(" = ?");
bindArgs[i++] = entry.getValue();
}
SQLiteStatement statement = mDB.compileStatement(query.toString());
for (i = 0; i < bindArgs.length; i++) {
DatabaseUtils.bindObjectToProgram(statement, i + 1, bindArgs[i]);
}
try {
mId = statement.simpleQueryForLong();
} finally {
statement.close();
}
}
}
}
catch (NullPointerException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
if (mActivity != null) { mActivity.onLangInserted(mId); }
super.onPostExecute(result);
}
}
这个 InsertLangTask 类包含在 Fragment 类中,其中我只实现 onCreate()、onAttach() 和 onDetach(),我还在内部创建了一个方法来初始化成员(不能在构造函数中这样做,因为它在 Fragment 类中必须为空)。我将 AsyncTask 包装在这个 Fragment 类中,以便保留我的 mId 成员并将其传递回我的活动,即使配置已更改并且活动已被破坏。我知道不完全是长期运行的情况,但它可能是。以下是该课程的部分内容:
public class InsertLangFragment extends Fragment {
public static interface OnLangInsertedListener {
void onLangInserted(long id);
}
SQLiteDatabase mDB = null;
ContentValues mCV = null;
private OnLangInsertedListener mActivity = null;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = activity;
}
public void RunTask(SQLiteDatabase db, ContentValues cv) {
new InsertLangTask().execute();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public void onDetach() {
super.onDetach();
mActivity = null;
}
}
在我的活动中,当我想开始这个过程时,我只是写这个:
InsertLangFragment fragment = new InsertLangFragment();
getFragmentManager().beginTransaction().add(fragment, "insertTaskFragment").commit();
fragment.RunTask(mSQLiteDatabase, mContentValues);
在实现的回调中获取mId
public void onLangInserted(long id) {
}
我使用了 setRetainInstance(true) 所以这个片段永远不会被破坏(除了后退按钮)并且将一直位于内存中。问题是我应该如何正确销毁片段实例?我想我有三种可能的结果:
1)没有必要销毁这些碎片。
2) 我应该把 getFragmentManager().remove("insertTaskFragment").commit() 放在我的活动中 onLangInserted() 的末尾
3) 我应该把 setRetainInstance(false) 放在 AsyncTask 中 onPostExecute() 的末尾。
请给我一个建议,我应该如何正确管理这个片段。
谢谢你。请不要太严格,我是新手。