【问题标题】:Android sql multiple fragments errorAndroid sql 多片段报错
【发布时间】:2016-03-19 10:43:25
【问题描述】:

我有一个包含多个片段的应用。在一个片段中,用户输入存储到 sql 表中的信息。在另一个片段中,从该表中读取数据(目前只是将其记录到控制台以进行测试)。保存到数据库可以正常工作,但是当我尝试读取数据时出现错误。

我的 DBHelper 类具有以下读取/插入方法:

public class DBHelper extends SQLiteOpenHelper {

    public boolean insertSubject(Integer id, String date, String RA, Integer condition, Integer age, String sex)
    {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(SUBJECTS_ID, id);
        contentValues.put(SUBJECTS_DATE, date);
        contentValues.put(SUBJECTS_RA, RA);
        contentValues.put(SUBJECTS_CONDITION, condition);
        contentValues.put(SUBJECTS_AGE, age);
        contentValues.put(SUBJECTS_SEX, sex);
        db.insertOrThrow(SUBJECTS_TABLE_NAME, null, contentValues);
        db.close();
        return true;
    }

    public boolean getSubject(Short subNum){
        SQLiteDatabase db = this.getReadableDatabase();
        String query = "SELECT * FROM subjects WHERE " + SUBJECTS_ID + "=" + subNum;

        Cursor c = db.rawQuery(query, null);

        while (c.moveToNext()) {
            String result_0=c.getString(0);
            String result_1=c.getString(1);

            Log.d("query", result_0);
            Log.d("query", result_1);
        }
        c.close();
        db.close();

        return true;
    }
}

在我的用户创建片段中,我创建了一个新的 DBHelper:

@Override
public void onActivityCreated(Bundle savedInstanceState){
    super.onActivityCreated(savedInstanceState);
    db = new DBHelper(getActivity());
}

然后创建视图:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        coordinatorLayout = (CoordinatorLayout) getActivity().findViewById(R.id.coordinator_layout);
        View view = inflater.inflate(R.layout.fragment_new, container, false);

        mainActivity = (MainActivity) getActivity();

        //Listener for create button
        createButton = (Button) view.findViewById(R.id.input_submit);
        createButton.setOnClickListener(this);

        // Inflate the layout for this fragment
        return view;
    }

创建按钮有一个onClick 监听器:

@Override
public void onClick(View v) {

    //Some form validation things go here

        //write to database
        try {
            db.insertSubject(
                    Integer.parseInt(subNum),
                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()),
                    ra,
                    Integer.parseInt(condition),
                    Integer.parseInt(age),
                    sex);

            //Store subject number for use throughout
            mainActivity.subNum = Short.parseShort(subNum);
            mainActivity.subCreated = true;

        } catch (SQLiteConstraintException e){
            Snackbar.make(coordinatorLayout, "Subject number already exists", Snackbar.LENGTH_SHORT).show();
            subNumWrapper.requestFocus();
        }
}

所有这些都保存到数据库中。子编号保存到主要活动中,以便稍后在查询数据库时使用它

但是,当尝试从数据库中读取数据时,我遇到了一些问题。在那个片段中,我的onActivityCreated 方法实际上与上面的片段相同。然后在onCreateView,基本和上面一样,只是增加了调用DBHelper方法:

db.getSubject(mainActivity.subNum);

我收到以下错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean come.example.test.DBHelper.getSubject(java.lang.Short)' on a null object reference

我认为这意味着它不知道db的存在?

为什么我在两个片段类中都以完全相同的方式(onActivityCreated)定义了 db?为什么这在主题创建片段中有效,但在查询框架中无效?

【问题讨论】:

  • stackoverflow.com/a/32656807/3697191 onActivityCreated() 在 onCreateView() 之后被调用。在您的插入片段中,插入发生在单击时,这是事件驱动的,到那时, onActivityCreated() 将被执行。从 db 读取时,情况并非如此。

标签: android android-fragments android-sqlite


【解决方案1】:

为了保持原创,

您正在寻找的答案在这里:https://stackoverflow.com/a/32656807/3697191

在您的插入片段中,调用按这样的顺序发生

onCreateView() //db still null
onActivityCreated() //db instantiated
onClick() //User clicked, db is not null

在您从 db 片段中读取时

onCreateView() //db still null
//Uh oh, we tried to read from db, NullPointerException
onActivityCreated() //db instantiated

【讨论】:

  • 那么这是否意味着大多数/所有数据库读/写代码(通常)应该存在于onActivityCreated() 中?
  • 如果您需要在视图中呈现数据,请在 onCreateView() 中执行数据库工作(实例化和获取)。但请考虑在后台线程中进行数据库工作,并在获取数据后立即更新视图,因为如果数据获取需要很长时间并且如果在 UI 线程上完成,它可能会使您的应用程序无响应
猜你喜欢
  • 2016-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多