setRetainInstance(true)时,在没有UI的情况下释放Fragment实例

时间:2013-05-29 07:54:14

标签: android android-fragments android-asynctask orientation

我需要在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中必须为空类)。我在这个Fragment类中包装了AsyncTask,以便保留我的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)我应该在我的活动中的onLangInserted()结尾处放置getFragmentManager()。remove(“insertTaskFragment”)。commit() 3)我应该在AsyncTask中onPostExecute()的末尾放置setRetainInstance(false)。

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

0 个答案:

没有答案