Android 将上下文从片段传递到SQLiteOpenHelper类时发生NullPointerException

Android 将上下文从片段传递到SQLiteOpenHelper类时发生NullPointerException,android,nullpointerexception,Android,Nullpointerexception,此代码在API级别21中运行良好,但在API级别19中不起作用。它正在生成NullPointerException 我在谷歌上查到了很多与此相关的问题,但这些问题都没有帮助 我从一个子片段调用SQliteOpenHelper,下面是我的代码,其中有错误: // This is my Chatbox class which a childfragment and // I am calling this method to pass values in sqlite class private

此代码在API级别21中运行良好,但在API级别19中不起作用。它正在生成NullPointerException

我在谷歌上查到了很多与此相关的问题,但这些问题都没有帮助

我从一个子片段调用SQliteOpenHelper,下面是我的代码,其中有错误:

// This is my Chatbox class which a childfragment and
// I am calling this method to pass values in sqlite class

 private void saveConversation(String profile_name,String profile_id,String message,String who){
    sqLite = new SQLite(getContext());
    SQLiteDatabase sqLiteDatabase = sqLite.getWritableDatabase();
    sqLite.onCreate(sqLiteDatabase);
    sqLite.insert(profile_name, profile_id, message, who);
}


//Sqlite class
public class SQLite extends SQLiteOpenHelper {
     SQLiteDatabase sqLiteDatabase  =  this.getWritableDatabase();
     ContentValues contentValues;
    Context context;

    public static final String DatabaseName = "Communication";
    public static final String TableName1  = "ChatConversation";
    public static final int DatabaseVersion = 2;

    public SQLite(Context context) {
        super(context, DatabaseName, null, DatabaseVersion);
        this.context = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
            Toast.makeText(context,"on create table is called !!",Toast.LENGTH_SHORT).show();
            db.execSQL("CREATE TABLE IF NOT EXISTS "+TableName1+"(_id INTEGER PRIMARY KEY AUTOINCREMENT,profilename VARCHAR(50),profileid VARCHAR(50),message VARCHAR(255),who VARCHAR(20))");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public void insert(String profilename,String profileid ,String message, String who){
        Toast.makeText(context,"insert database was called",Toast.LENGTH_LONG).show();
        contentValues = new ContentValues();
        contentValues.put("profilename",profilename);
        contentValues.put("profileid",profileid);
        contentValues.put("message",message);
        contentValues.put("who",who);
        long id = sqLiteDatabase.insert(SQLite.TableName1,null,contentValues);
        if(id>0){
           Toast.makeText(context,"successfully inserted", LENGTH_LONG).show();
        }else{
            Toast.makeText(context,"Something went wrong", LENGTH_LONG).show();
        }
    }

}
这是我的错误:

com.example.shuresnepali.communicationpost, PID: 21374
   java.lang.NullPointerException
   at android.widget.Toast.<init>(Toast.java:117)
   at android.widget.Toast.makeText(Toast.java:275)
   at com.example.shuresnepali.communicationpost.SQLite.onCreate(SQLite.java:28)
   at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:252)
   at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
   at com.example.shuresnepali.communicationpost.SQLite.<init>(SQLite.java:13)
   at com.example.shuresnepali.communicationpost.Chat_box.saveConversation(Chat_box.java:283)
   at com.example.shuresnepali.communicationpost.Chat_box.onClick(Chat_box.java:149)
   at android.view.View.performClick(View.java:4652)
   at android.view.View$PerformClick.run(View.java:19318)
   at android.os.Handler.handleCallback(Handler.java:733)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:146)
   at android.app.ActivityThread.main(ActivityThread.java:5641)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:515)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1288)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1104)
   at dalvik.system.NativeStart.main(Native Method)
com.example.shuresnapali.communicationpost,PID:21374
java.lang.NullPointerException
在android.widget.Toast.(Toast.java:117)
位于android.widget.Toast.makeText(Toast.java:275)
在com.example.shuresnapali.communicationpost.SQLite.onCreate(SQLite.java:28)上
位于android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:252)
位于android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
在com.example.shuresnapali.communicationpost.SQLite.(SQLite.java:13)
在com.example.shuresnapali.communicationpost.Chat_-box.saveConversation(Chat_-box.java:283)
在com.example.shuresnapali.communicationpost.Chat_-box.onClick(Chat_-box.java:149)
在android.view.view.performClick上(view.java:4652)
在android.view.view$PerformClick.run(view.java:19318)
位于android.os.Handler.handleCallback(Handler.java:733)
位于android.os.Handler.dispatchMessage(Handler.java:95)
位于android.os.Looper.loop(Looper.java:146)
位于android.app.ActivityThread.main(ActivityThread.java:5641)
位于java.lang.reflect.Method.Invokenactive(本机方法)
位于java.lang.reflect.Method.invoke(Method.java:515)
在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1288)上
位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1104)
在dalvik.system.NativeStart.main(本机方法)

尝试在片段中使用
getActivity()
来获取
上下文

private void saveConversation(String profile_name,String profile_id,String message,String who){
        sqLite = new SQLite(getParentFragment().getActivity());
        SQLiteDatabase sqLiteDatabase = sqLite.getWritableDatabase();
        sqLite.onCreate(sqLiteDatabase);
        sqLite.insert(profile_name, profile_id, message, who);
    }
使用getActivity()获取片段中的上下文

 private void saveConversation(String profile_name,String profile_id,String message,String who){
        sqLite = new SQLite(getActivity());
        SQLiteDatabase sqLiteDatabase = sqLite.getWritableDatabase();
        sqLite.onCreate(sqLiteDatabase);
        sqLite.insert(profile_name, profile_id, message, who);
    }
您调用
getWritableDatabase()
太早了。在Java中,成员初始值设定项在构造函数体之前运行(显式超级构造函数调用除外),并且您只在构造函数体中初始化
上下文
getWritableDatabase()
依次调用
onCreate()
以使用尚未初始化的
上下文
字段。进一步阅读:

删除此字段,或将其初始化推迟到构造函数体

另一方面,您不应该自己调用
onCreate()


为什么它在API 21而不是19上“起作用”,很可能是因为在API 21设备/仿真器上,您已经有了一个同名的数据库文件,该文件是使用早期版本的应用程序创建的,没有此错误
getWritableDatabase()
仅在数据库文件不存在时调用
onCreate()

感谢大家的帮助我通过…在插入数据期间传递上下文来解决这个问题,并从初始化中删除了getwriteabledatabase

 private void saveConversation(String profile_name,String profile_id,String message,String who){
        sqLite = new SQLite(getParentFragment().getContext());
        SQLiteDatabase sqLiteDatabase = sqLite.getWritableDatabase();
        sqLite.onCreate(sqLiteDatabase);
        sqLite.insert(profile_name, profile_id, message, who,sqLiteDatabase);
    }
//and after this
 public void insert(String profilename,String profileid ,String message, String who,SQLiteDatabase sqLiteDatabase){
        Toast.makeText(context,"insert database was called",Toast.LENGTH_LONG).show();
        contentValues = new ContentValues();
        contentValues.put("profilename",profilename);
        contentValues.put("profileid",profileid);
        contentValues.put("message",message);
        contentValues.put("who",who);
        long id = sqLiteDatabase.insert(SQLite.TableName1,null,contentValues);
        if(id>0){
           Toast.makeText(context,"successfully inserted", LENGTH_LONG).show();
        }else{
            Toast.makeText(context,"Something went wrong", LENGTH_LONG).show();
        }
    }

感谢您的快速响应,但仍然没有任何更改得到与以前相同的错误…我正在使用childfragment,这有关系吗?仍然不起作用我还尝试了getParentFragment().getcontex(),但仍然得到相同的错误。它在API 21级中工作,所以你能考虑一下这个问题吗?但根本无法在api 19中工作。@舒尔检查此链接可能重复:。顺便说一句,重新打开副本是一种反竞争策略-pattern@ModularSynth我重新打开,因为我发现如果有更具体的问题,关闭问题与一般的问题解决方法是重复的,没有任何帮助。这是一个很好的参考,但在具体问题上很少有帮助。谢谢@laalto的帮助,我只是在sqlit中插入数据时通过insert方法传递SQLITEDABASE。塔克斯:你的回答很好supportive@laalto每个NullPointerException都有相同的原点。因此,看到一个,看到所有。通过正确实例化过早引用的对象,它们都已修复。副本应该保留。由于NPE不在
SQLiteOpenHelper.getDatabaseLocked()
中,因此上下文本身没有问题。请清除更多有关此内容的信息?我也听说过这个问题,但无法理解到底发生了什么??如果您能帮助我,那就太好了。请删除此
getWritableDatabase()
字段初始值设定项,并删除调用
onCreate()
的行。调用
getWritableDatabase()
在需要
SQLiteDatabase()
的方法中初始化本地变量。
 private void saveConversation(String profile_name,String profile_id,String message,String who){
        sqLite = new SQLite(getParentFragment().getContext());
        SQLiteDatabase sqLiteDatabase = sqLite.getWritableDatabase();
        sqLite.onCreate(sqLiteDatabase);
        sqLite.insert(profile_name, profile_id, message, who,sqLiteDatabase);
    }
//and after this
 public void insert(String profilename,String profileid ,String message, String who,SQLiteDatabase sqLiteDatabase){
        Toast.makeText(context,"insert database was called",Toast.LENGTH_LONG).show();
        contentValues = new ContentValues();
        contentValues.put("profilename",profilename);
        contentValues.put("profileid",profileid);
        contentValues.put("message",message);
        contentValues.put("who",who);
        long id = sqLiteDatabase.insert(SQLite.TableName1,null,contentValues);
        if(id>0){
           Toast.makeText(context,"successfully inserted", LENGTH_LONG).show();
        }else{
            Toast.makeText(context,"Something went wrong", LENGTH_LONG).show();
        }
    }