首页 > 解决方案 > “尝试在空对象引用上调用虚拟方法”同时显示来自 sqlite 数据库的数据

问题描述

我想从数据库中检索详细信息并使用文本视图将它们打印在一个选项卡式活动片段中。但是,我得到空对象引用。关于我为什么会收到这个错误以及我应该做些什么来避免这种错误的任何线索?


这是我的片段(fragment_home_left.class),我必须在其中显示数据库中的记录

package com.rishabh.admin.bucomp;

import android.database.Cursor;
import android.os.Bundle;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class fragment_home_left extends android.support.v4.app.Fragment implements View.OnClickListener {

    Login_Signup_DB_adapter db_adapter;
    String TAG = "FRAGMENT_HOME_LEFT";

//Button addGroup ,addMember;
    //EditText new_group_edit_text;

    Button display_users;

    TextView display_box;
    String details_recieved;


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

        View view = inflater.inflate(R.layout.fragment_main_activity_home_left, container, false);

        //addGroup = (Button) view.findViewById(R.id.button_add_Group);
        display_users = (Button)view.findViewById(R.id.button_display_users);
        //addMember = (Button) view.findViewById(R.id.button_display_users);
        //new_group_edit_text = (EditText) view.findViewById(R.id.editText_fragment_left);
        display_box = (TextView) view.findViewById(R.id.editText_displayBox);

        //addMember.setOnClickListener(this);
        display_users.setOnClickListener(this);
        //addGroup.setOnClickListener(this);
        //To display the records of all the users registered within the database
        //Display_user_data();
        return view;
    }
    @Override
    public void onClick(View v) {
        if(v.getId() == R.id.button_display_users)
        {
            //details_recieved = new_group_edit_text.getText().toString().trim();
            //Toast.makeText(getActivity(),"Member added "+details_recieved,Toast.LENGTH_LONG).show();

            Log.i(TAG, "onClick: Display users button clicked, calling display function");
            Fetch_user_data();
        }else{
            Log.i(TAG, "onClick: NO ID BUTTON");
        }
    }

    private void Fetch_user_data() {
        Log.i(TAG, "Fetch_user_data: CALLING FETCH USER DATA METHOD");
        Cursor cursor = db_adapter.getAll_users();
        Log.i(TAG, "Fetch_user_data: CURSOR RECIEVED SOMETHING");
        Display_user_data(cursor);

    }

    private void Display_user_data(Cursor cursor) {
        Log.i(TAG, "Display_user_data: CALLED DISPLAY_USER_DATA");
        String message = "";

        if(cursor!= null && cursor.getCount() > 0){
            Log.i(TAG, "Display_user_data: DO WHILE LOOP WILL BE EXECUTED");
            cursor.moveToFirst();
            do{
                int user_id;
                String user_name,user_email,user_password;

                user_id = cursor.getInt(db_adapter.USER_COL_ROW_ID);
                user_name = cursor.getString(db_adapter.USER_COL_NAME);
                user_email = cursor.getString(db_adapter.USER_COL_EMAIL);
                user_password = cursor.getString(db_adapter.USER_COL_PASSWORD);

                message = message+"id="+user_id+","+"name="+user_name+","+"email="+user_email
                        +","+"pass="+user_password+"\n";
                Log.i(TAG, "Display_user_data: NEW MESSAGE STRING APPENDED");
            }while(cursor.moveToNext());
            cursor.close();
            Log.i(TAG, "Display_user_data: CURSOR IS CLOSED");
        }
        Log.i(TAG, "Display_user_data: CALLING SET_DATA_EDIT_TEXT METHOD");
        set_data_in_editText(message);
    }

    private void set_data_in_editText(String message) {
        Log.i(TAG, "set_data_in_editText: NOW SETTING MESSAGE TO TEXT VIEW");
        display_box.setText(message);
    }


}

与上述片段链接的 xml 布局(fragment_main_activity_home_left.xml)

<?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent" android:layout_height="match_parent">

    <Button
        android:id="@+id/button_display_users"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_marginBottom="67dp"
        android:layout_marginEnd="140dp"
        android:background="@color/Material_red"


android:elegantTextHeight="true"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        android:text="Display_users"
        android:textColor="@android:color/background_light" />

    <EditText
        android:id="@+id/editText_displayBox"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/button_display_users"
        android:layout_alignParentStart="true"
        android:layout_marginBottom="10dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="Name" />

</RelativeLayout>

这是存储sqlite数据库中的数据并与之交互的数据库助手类

package com.rishabh.admin.bucomp;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class Login_Signup_DB_adapter {

    //Database constants area

    private static final String TAG = "DATABASE ADAPTER";
    public static final String DB_NAME = "bucomp_db";
    public static final int DB_VERSION = 2;

    //Current_active_user_id stores the id of the current user
    public static long Current_active_user_id = -2;

    //Current_active_group_id stores the group id of the current group
    public static long Current_active_group_id = 0;

    private final Context context;
    private DBHelper MYDBHelper;
    private SQLiteDatabase db_readable, db_writable;

    //End of database constants area



    //column names for USER

    public static final String DB_TABLE_USER = "user_table";

    public static final String USER_KEY_ROWID = "user_id";
    public static final String USER_KEY_NAME = "user_name";
    public static final String USER_KEY_EMAIL = "user_email";
    public static final String USER_KEY_PASSWORD = "user_password";

    //column number for all the columns created above

    public static final int USER_COL_ROW_ID = 0;
    public static final int USER_COL_NAME = 1;
    public static final int USER_COL_EMAIL = 2;
    public static final int USER_COL_PASSWORD = 3;

    //USER_ALL_KEYS stores the list of all the columns created

    public static final String[] USER_ALL_KEYS = {
            USER_KEY_ROWID, USER_KEY_NAME, USER_KEY_EMAIL, USER_KEY_PASSWORD
            };

    //create table query to be used by the database helper

    private static final String DB_CREATE_QUERY_USER =
            "create table " + DB_TABLE_USER
            + " (" + USER_KEY_ROWID + " integer primary key autoincrement, "
            + USER_KEY_NAME + " text not null, "
            + USER_KEY_EMAIL + " text not null, "
            + USER_KEY_PASSWORD + " text not null"
            + ");";


    //column names for GROUPS within USERS

    public static final String DB_TABLE_GROUP = "group_table";

    public static final String GROUP_KEY_ROWID = "group_id";
    public static final String GROUP_KEY_NAME = "group_name";
    public static final String GROUP_KEY_TOTAL_BUDGET = "group_budget";
    public static final String GROUP_KEY_TOTAL_MEMBERS = "group_total_members";
    public static final String GROUP_KEY_LINKED_USER_ID = "group_linked_user_id";

    //column number for all the columns created above

    public static final int GROUP_COL_ROW_ID = 0;
    public static final int GROUP_COL_NAME = 1;
    public static final int GROUP_COL_TOTAL_BUDGET = 2;
    public static final int GROUP_COL_TOTAL_MEMBERS = 3;

    //GROUP_ALL_KEYS stores the list of all the columns created

    public static final String[] GROUP_ALL_KEYS = {
            GROUP_KEY_ROWID,
            GROUP_KEY_NAME,
            GROUP_KEY_TOTAL_BUDGET,
            GROUP_KEY_TOTAL_MEMBERS,
            GROUP_KEY_LINKED_USER_ID
    };

    //create table query to be used by the database helper

    private static final String DB_CREATE_QUERY_GROUP =
            "create table " + DB_TABLE_GROUP
                    + " (" + GROUP_KEY_ROWID + " integer primary key autoincrement, "
                    + GROUP_KEY_NAME + " text not null, "
                    + GROUP_KEY_TOTAL_BUDGET + " integer, "
                    + GROUP_KEY_TOTAL_MEMBERS + " integer, "
                    + GROUP_KEY_LINKED_USER_ID + " integer not null"
                    + ");";


    //column names for MEMBERS within GROUPS

    public static final String DB_TABLE_MEMBER = "member_table";

    public static final String MEMBER_KEY_ROWID = "member_id";
    public static final String MEMBER_KEY_NAME = "member_name";
    public static final String MEMBER_KEY_LINKED_GROUP_ID = "member_linked_group_id";
    public static final String MEMBER_KEY_LINKED_USER_ID = "member_linked_user_id";

    //column number for all the columns created above

    public static final int MEMBER_COL_ROW_ID = 0;
    public static final int MEMBER_COL_NAME = 1;
    public static final int MEMBER_COL_LINKED_GROUP_ID = 2;
    public static final int MEMBER_COL_LINKED_USER_ID = 3;

    //MEMBER_ALL_KEYS stores the list of all the columns created

    public static final String[] MEMBER_ALL_KEYS = {
            MEMBER_KEY_ROWID,
            MEMBER_KEY_NAME,
            MEMBER_KEY_LINKED_GROUP_ID,
            MEMBER_KEY_LINKED_USER_ID
    };

    //create table query to be used by the database helper

    private static final String DB_CREATE_QUERY_MEMBER =
            "create table " + DB_TABLE_MEMBER
                    + " ("
                    + MEMBER_KEY_ROWID + " integer primary key autoincrement, "
                    + MEMBER_KEY_NAME + " text not null, "
                    + MEMBER_KEY_LINKED_GROUP_ID + " integer not null, "
                    + MEMBER_KEY_LINKED_USER_ID + " integer not null"
                    + ");";


    public Login_Signup_DB_adapter(Context context) {
        this.context = context;
        MYDBHelper = new DBHelper(context);
    }

    public Login_Signup_DB_adapter open_database(){
        db_writable = MYDBHelper.getWritableDatabase();
        db_readable = MYDBHelper.getReadableDatabase();
        return this;
    }

    public void close_database(){
        MYDBHelper.close();
    }

    //insert new user in the user table

    public long SignUp_new_user(String UserName, String UserEmail, String UserPassword){

        //set up contentValues to insert the data into the required DB

        ContentValues contentValues = new ContentValues();

        //feed data into the contentValues

        contentValues.put(USER_KEY_NAME, UserName);
        contentValues.put(USER_KEY_EMAIL, UserEmail);
        contentValues.put(USER_KEY_PASSWORD, UserPassword);

        //insert the data stored in the contentValues into the DB_USER
        //The return statement will return the id of the newly entered user in the user table
        //this is the reason why the return type is long
        Log.i(TAG, "SignUp_new_user: WRITING NEW USER IN THE DATABSE");
        return db_writable.insert(DB_TABLE_USER, null, contentValues);
    }


    public long Check_Login_user(String UserName, String UserPassword)
    {
        Log.i(TAG, "Check_Login_user: ENTERED Check_Login_user");
        //db_readable = MYDBHelper.getReadableDatabase();
        Log.i(TAG, "Check_Login_user: READABLE DB SET");
        /* To verify if the user if already registered and take appropriate actions as below:
        1. If the user is already registered and enters correct details, grant login access.
        2. If the user is already registered but enters incorrect details, revoke access.
        3. If the user is not registered, simply revoke the access.

        NOTE: If possible, try to redirect the user to the signUp page if CASE 3 occurs.

        */

        String where = USER_KEY_NAME+"=?";
        String[] args = {UserName};
        Log.i(TAG, "Check_Login_user: QUERYING DB FOR LOGIN");

        Cursor cursor = db_readable.query(
                DB_TABLE_USER,
                USER_ALL_KEYS,
                where,
                args,
                null,
                null,
                null
        );

        Log.i(TAG, "Check_Login_user: CURSOR POPULATED");
        if (cursor.getCount() > 0)
        {
            Log.i(TAG, "Check_Login_user: CURSOR IS NOT NULL");
            cursor.moveToFirst();
            String password = cursor.getString(USER_COL_PASSWORD);
            String username = cursor.getString(USER_COL_NAME);
            String email = cursor.getString(USER_COL_EMAIL);

            Log.i(TAG, "Check_Login_user: DATA FETCHED FROM DB IS :\n"
                    + "NAME: " + username + "\n"
                    + "Email : " + email + "\n"
                    + "Password : " + password + "\n"
            );
            Log.i(TAG, "Check_Login_user: MATCHING :" + username + " with " + UserName
            + " and " + password + " with " + UserPassword +"\n");
            if (username.equals(UserName) && password.equals(UserPassword)) {
                Log.i(TAG, "Check_Login_user: USER FOUND \n");
                Current_active_user_id = cursor.getInt(USER_COL_ROW_ID);
                Log.i(TAG, "Check_Login_user: CURRENT USER ID IS :" + Current_active_user_id + "\n");


            } else {
                Log.i(TAG, "Check_Login_user: INCORRECT PASSWORD");
                Current_active_user_id = -2;
            }
        }else{
            Log.i(TAG, "Check_Login_user: NO SUCH USERNAME");
            Current_active_user_id = -4;
        }
        return Current_active_user_id;
    }

    //insert new group of the current user in the group table

    public long insert_Row_group(String GroupName, int TotalBudget, int TotalMembers){

        //set up contentValues to insert the data into the required DB

        ContentValues contentValues = new ContentValues();

        //feed data into the contentValues

        contentValues.put(GROUP_KEY_NAME, GroupName);
        contentValues.put(GROUP_KEY_TOTAL_BUDGET, TotalBudget);
        contentValues.put(GROUP_KEY_TOTAL_MEMBERS, TotalMembers);



        /*
        insert the data stored in the contentValues into the DB_GROUP
        The return statement will return the id of the newly entered user in the user table
        this is the reason why the return type is long
        */

        return db_writable.insert(DB_TABLE_GROUP, null, contentValues);
    }

    //insert new member of the current group in the member table

    public long insert_Row_member(){
        return -1;
    }

    //delete specific user in the user table

    public boolean delete_Row_user(){
        return true;
    }

    //delete specific group of the current user in the group table

    public boolean delete_Row_group(){
        return true;
    }

    //delete specific member in the group of the current user from the member table

    public boolean delete_Row_member(){
        return true;
    }

    //delete all the users from the user table

    public void delete_all_users(){

    }

    //delete all the groups of the current user from the group table

    public void delete_all_groups(){

    }

    //delete all the members in the current group of the active user from the member table

    public void delete_all_members(){

    }


    //retrieve all the data present in the user table.

    public Cursor getAll_users(){
        Log.i(TAG, "getAll_users: ENTERED getAll_users");

        Cursor cursor = db_readable.query(
                DB_TABLE_USER,
                USER_ALL_KEYS,
                null,
                null,
                null,
                null,
                null,
                null
        );

        if(cursor != null)
        {   Log.i(TAG, "getAllRows_users: DATA FETCHED SUCCESSFULLY");
            cursor.moveToFirst();
        }
        else {
            Log.i(TAG, "getAllRows_users: NO DATA FOR USERS FETCHED");
        }
        return cursor;
    }

    //retrieve all the data present in the group table for the current user

    //public Cursor getAllRows_groups(){

    //}

    //retrieve all the data present in the member table for the specific group of current user

    //public Cursor getAllRows_members(){

    //}





    //Creating private DataBase Helper class to initialize the database

    private static class DBHelper extends SQLiteOpenHelper{
        public DBHelper(Context context) {
            super(context, DB_NAME, null, DB_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            //initialize user table
            db.execSQL(DB_CREATE_QUERY_USER);
            //initialize group table
            db.execSQL(DB_CREATE_QUERY_GROUP);
            //initialize member table
            db.execSQL(DB_CREATE_QUERY_MEMBER);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            //if table columns are changed or updated, delete the previous version

            db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE_USER);
            db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE_GROUP);
            db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE_MEMBER);
            //and re-initialize the databases with updated parameters
            onCreate(db);

        }
    }//End of DBHelper class
}//End Login_Signup_DB_adapter class

这是当我单击“显示用户”按钮时出现的日志错误。

05-20 08:37:20.413 1818-1818/? I/LOGIN: checkInDataBase: LOGIN USER EXISTS WITH ID :1
05-20 08:37:25.106 594-938/? I/WindowManager: Destroying surface Surface(name=com.rishabh.admin.bucomp/com.rishabh.admin.bucomp.MainActivity_Login) called by com.android.server.wm.WindowStateAnimator.destroySurface:2014 com.android.server.wm.WindowStateAnimator.destroySurfaceLocked:881 com.android.server.wm.WindowState.destroyOrSaveSurface:2073 com.android.server.wm.WindowManagerService.tryStartExitingAnimation:3017 com.android.server.wm.WindowManagerService.relayoutWindow:2897 com.android.server.wm.Session.relayout:215 android.view.IWindowSession$Stub.onTransact:286 com.android.server.wm.Session.onTransact:136 

<LOG ERROR>
05-20 08:37:33.637 1818-1818/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.rishabh.admin.bucomp, PID: 1818
    java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor com.rishabh.admin.bucomp.Login_Signup_DB_adapter.getAll_users()' on a null object reference
        at com.rishabh.admin.bucomp.fragment_home_left.Fetch_user_data(fragment_home_left.java:72)
        at com.rishabh.admin.bucomp.fragment_home_left.onClick(fragment_home_left.java:62)
        at android.view.View.performClick(View.java:5609)
        at android.view.View$PerformClick.run(View.java:22259)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6077)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

标签: javaandroiddatabasesqlitenullpointerexception

解决方案


你还没有初始化你db_adapter的这就是为什么db_adapternull并且你正在调用一个Login_Signup_DB_adapter类的函数。所以,你需要db_adapter像这样在onCreateView类中fragment_home_left初始化

db_adapter = new Login_Signup_DB_adapter(this);

推荐阅读