2

我需要向我的 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() 的末尾。

请给我一个建议,我应该如何正确管理这个片段。
谢谢你。请不要太严格,我是新手。

4

0 回答 0