java - Android 阻止应用程序在启动时查询空数据库

标签 java android sqlite

我正在构建一个简单的待办事项/任务应用程序,其中任务以回收器/卡片 View 布局呈现,并且在选择任务时,用户将看到该特定任务的“详细” View 。我正在使用 Genymotion 模拟器测试我的应用程序。我的问题是应用程序在使用 NPE 启动后立即崩溃。

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.api.client.util.DateTime.toString()' on a null object reference
            at com.github.idclark.forgetmenot.TaskAdapter.onBindViewHolder(TaskAdapter.java:35)
            at com.github.idclark.forgetmenot.TaskAdapter.onBindViewHolder(TaskAdapter.java:17)

虽然我不完全确定,但我认为这是因为我还没有向数据库输入任何数据。首先从我的主要 Activity 膨胀的 fragment 中查询数据库。

public static class PlaceholderFragment extends Fragment {

        Activity mActivity;
        RecyclerView mRecyclerView;
        TaskAdapter taskAdapter;
        AddFloatingActionButton mFabView;
        CheckBox mCheckBox;

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {

            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            mRecyclerView = (RecyclerView) rootView.findViewById(R.id.cardList);
            mFabView = (AddFloatingActionButton) rootView.findViewById(R.id.normal_plus);

            mFabView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    Intent createTaskIntent = new Intent(v.getContext(), EditActivity.class);
                    startActivity(createTaskIntent);
                }
            });

            taskAdapter = new TaskAdapter(new TaskTableController(getActivity()).getAllTasksForUser());
            return rootView;
        }

我的TaskAdapter预计 ArrayList<Task>

public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.TaskViewHolder> {

    private List<Task> taskList;
    OnItemClickListener mItemClickListener;

    public TaskAdapter(List<Task> taskList) {
        this.taskList = taskList;
    }

    @Override
    public int getItemCount() {
        return taskList.size();
    }

    @Override
    public void onBindViewHolder(TaskViewHolder taskViewHolder, int i) {
        Task task = taskList.get(i);
        taskViewHolder.mTitle.setText(task.getTitle());
        taskViewHolder.mUpdated.setText(task.getUpdated().toString());
        if (task.getStatus().equals("completed")) {
            taskViewHolder.mStatus.setChecked(true);
        } else taskViewHolder.mStatus.setChecked(false);

    }

    @Override
    public TaskViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

        View itemView = LayoutInflater.from(viewGroup.getContext()).
                inflate(R.layout.tasklist_layout, viewGroup, false);

        return new TaskViewHolder(itemView);
    }

对数据库的实际查询如下所示

public List<Task> getAllTasksForUser() {
        final String QUERY_ALL_RECORDS = "SELECT * FROM " + TaskEntry.TABLE_NAME;

        List<Task> taskList = new ArrayList<>();
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(QUERY_ALL_RECORDS, null);
        if (cursor.getCount() > 0) {
            while (cursor.moveToNext()) {
                Task task = new Task();
                int TaskId = cursor.getColumnIndex(TaskEntry.COLUMN_TASK_ID);
                task.setId(cursor.getString(TaskId));
                task.setTitle(cursor.getString(cursor.getColumnIndex(TaskEntry.COLUMN_TASK_TITLE)));
                task.setDue(new DateTime(cursor.getString(cursor.getColumnIndex(TaskEntry.COLUMN_TASK_DUE))));
                task.setNotes(cursor.getString(cursor.getColumnIndex(TaskEntry.COLUMN_TASK_NOTES)));
                taskList.add(task);
            }
        } else return taskList;
        db.close();
        return taskList;
    }

当应用程序首次安装在模拟器上时,数据库中没有数据,我认为这就是导致NPE的原因。我如何处理这种情况,以便如果没有数据我的 fragment 只显示一个空列表(即空白)。我已经在检查是否 cursor.getCount()大于 0,如果它不返回空列表给适配器。为了摆脱这个 NPE,我缺少什么?

最佳答案

崩溃最有可能发生在以下行:

    taskViewHolder.mUpdated.setText(task.getUpdated().toString());

task.getUpdate() 返回 null 并且您的应用程序崩溃。 我不明白你在哪里调用 setUpdated 。可能是您的某个 setter 这样做了,也可能是您忘记在代码中添加 setter。

有一点不相关的注意事项:如果您的任务列表为空,则您既不会关闭游标,也不会关闭数据库。

关于java - Android 阻止应用程序在启动时查询空数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31072956/

相关文章:

android - 在 Android 中的计时器内运行异步任务

android - 在 Android 上的 SQLite 中处理多个表 - 为什么这么复杂?

java - 从 SurfaceView 内部启动 Activity

Android 多列 SQLite 数据库

java - 应用程序引擎上的可靠分布式缓存 (Java)

java - 我的 Java Swing Designer 计算器无法运行。 (循环的等于按钮按下时会出错)

python - 提高sqlite中自连接的性能

sql - 根据条件(CASE?)选择不同的列并获取值来自的列名

java - 找不到与名称匹配的资源 - Android Studio

java - 如何检查列中是否存在特定数据