Android SQLite NullPointer 异常和堆栈溢出异常 [重复]

Posted

技术标签:

【中文标题】Android SQLite NullPointer 异常和堆栈溢出异常 [重复]【英文标题】:Android SQLite NullPointer Exception and stack overflow exception [duplicate] 【发布时间】:2017-03-31 12:59:13 【问题描述】:

有sql查询的线路出现NUllpointer异常和堆栈溢出异常。

display.java

 import android.app.Activity;
 import android.content.Context;
 import android.os.Bundle;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.widget.TextView;

  public class display extends Activity 
  private Context context;
  MyDBHandler helper

 @Override
  protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_display);
    helper = new MyDBHandler(context);

    Bundle nameValue=getIntent().getExtras();
    String vname=nameValue.getString("Name");
    TextView tvname=(TextView)findViewById(R.id.TVname);
    tvname.setText(vname);

    String dispname=helper.onSelect(vname);
    TextView tvaddress=(TextView)findViewById(R.id.TVaddress);
    tvaddress.setText(dispname);


  
   /*public void onDisplay()
    Bundle nameValue=getIntent().getExtras();
    if(nameValue==null)

    
    String vname=nameValue.getString("Name");
    String dispname=helper.onSelect(vname);
    TextView tvaddress=(TextView)findViewById(R.id.TVaddress);
    tvaddress.setText(dispname);
*/




@Override
public boolean onCreateOptionsMenu(Menu menu) 
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;


@Override
public boolean onOptionsItemSelected(MenuItem item) 
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) 
        return true;
    

    return super.onOptionsItemSelected(item);


MyDBHandler

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

public class MyDBHandler extends SQLiteOpenHelper 

private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "productDB.db";
public static final String TABLE_PRODUCTS = "products";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_NAME = "name";
public static final String COLUMN_ADDRESS = "address";


private final Context myContext;
public MyDBHandler(Context context) 
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    this.myContext = context;



    @Override
     public void onCreate(SQLiteDatabase db) 
    String query = "CREATE TABLE " + TABLE_PRODUCTS + "(" +
            COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
            COLUMN_NAME + " TEXT, " +
            COLUMN_ADDRESS + " TEXT " +
            ");";
    db.execSQL(query);
    String query1="INSERT INTO"+ TABLE_PRODUCTS + "(name,address) VALUES   
    ('name1,address1');";
    String query2="INSERT INTO"+ TABLE_PRODUCTS + "(name,address) VALUES   
    ('name2,address2');";
    db.execSQL(query1);
    db.execSQL(query2);



@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_PRODUCTS);
    onCreate(db);


public String onSelect(String sname)
    String dbString = "";
    SQLiteDatabase db = getWritableDatabase();
    String displayname= "SELECT address FROM"+ TABLE_PRODUCTS + " WHERE "+       


    COLUMN_NAME + "=\""+ sname + "\";";
    Cursor c = db.rawQuery(displayname, null);

   if (c.getString(c.getColumnIndex("address")) != null) 
           dbString = c.getString(c.getColumnIndex("address"));
   
    db.close();
    return dbString;
   

   

空指针异常

E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfocom.example.arjun.tablesqlite/com.example.arjun.tablesqlite.display: java.lang.NullPointerException
at com.example.arjun.tablesqlite.MyDBHandler.onSelect(MyDBHandler.java:57)
at com.example.arjun.tablesqlite.display.onCreate(display.java:27)

我在 MyDbHandler.java 的这一行收到 NullPointerException

SQLiteDatabase db = getWritableDatabase();  

在 display.java 的这一行......

String dispname=helper.onSelect(vname); 

【问题讨论】:

你能做 helper = new MyDBHandler(context);在 setContentView() 之后的 onCreate 中并尝试,在此之前将上下文初始化为 this 不相关,但你不应该在if(nameValue==null) 时使用return。这将退出onCreate 方法,这可能很糟糕 @Raghavendra 我遇到了同样的错误兄弟... @arjun 你能发布你更新的代码吗? 我说的是无关的——意思是它不能解决问题 【参考方案1】:

试试这个,

你还没有初始化上下文,你直接尝试用那个上下文初始化 DBHandler,所以它抛出了 NLP。

public class display extends Activity 

MyDBHandler helper;


@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_display);

    helper = new MyDBHandler(this);
   .... //your code

【讨论】:

这已经奏效了!!!但是现在我得到了这个 ==>E/SQLiteLog: (1) 在 "INTOproducts" 附近:语法错误 D/AndroidRuntime: 关闭 VM W/dalvikvm: threadid =1:线程以未捕获的异常退出(组=0x4100b2b8) E/AndroidRuntime:致命异常:main java.lang.RuntimeException:无法启动活动 ComponentInfocom.example.arjun.tablesqlite/com.example.arjun.tablesqlite.display :android.database.sqlite.SQLiteException:靠近“INTOproducts”:语法错误(代码 1):,编译时:INSERT INTOproducts(name,address) VALUES ('name1,address1'); @arjun 在该查询中的 INTO 之后给出空格 @arjun 试试这个:"INSERT INTO "+ TABLE_PRODUCTS + "(name,address) VALUES ('name1,address1');"和字符串 query2="INSERT INTO "+ TABLE_PRODUCTS + "(name,address) VALUES ('name2,address2');"; @Raghavendra ..它工作了!!!现在我将通过服务器尝试使用 phpmysql 的类似概念.. 我有一个疑问兄弟.. 我应该记住所有的编码开发应用程序?...【参考方案2】:

请尝试下面的 onSelect 方法并让我知道其中的任何错误:-

  public String onSelect(String sname) 
        String dbString = "";
        SQLiteDatabase db = this.getWritableDatabase();
        String displayname = "SELECT address FROM" + TABLE_PRODUCTS + " WHERE " +


                COLUMN_NAME + "='" + sname + "'";
        Cursor c = db.rawQuery(displayname, null);

/*
        if (c.getString(c.getColumnIndex("address")) != null) 
            dbString = c.getString(c.getColumnIndex("address"));
        
*/
        if (c.moveToFirst()) 
            if (c.getString(c.getColumnIndex("address")) != null) 
                dbString = c.getString(c.getColumnIndex("address"));
            else
                dbString="No Address";
            
        else
            dbString="No Address Found";
        
        db.close();
        return dbString;
    

还有这个:-

MyDBHandler helper = new MyDBHandler(this);

像下面这样改变这一行

String query1="INSERT INTO "+ TABLE_PRODUCTS + "(name,address) VALUES   
    ('name1','address1');";
String query2="INSERT INTO "+ TABLE_PRODUCTS + "(name,address) VALUES   
    ('name2','address2')";

您的数据库查询如下(供参考):-

INSERT INTO products (name,address) VALUES ('name1','address1');

您的查询构建如下:-

插入INTOproducts(姓名、地址)VALUES('name1'、'address1');

所以你得到了以下错误。

【讨论】:

我认为 this.getWritableDatabase() 应该可以解决您的问题。 我已经完成了这些更正..现在我收到了这个语法错误..... E/SQLiteLog: (1) near "INTOproducts": 语法错误 D/AndroidRuntime: 关闭 VM W /dalvikvm:threadid = 1:线程以未捕获的异常退出(组= 0x4100b2b8)E / AndroidRuntime:致命异常:main java.lang.RuntimeException:无法启动活动ComponentInfo com.example.arjun.tablesqlite/com.example.arjun .tablesqlite.display: android.database.sqlite.SQLiteException: near "INTOproducts": syntax error (code 1): , while compile: INSERT INTOproducts(name,address) VALUES ('name1,address1'); @arjun 您忘记在插入查询中的 INTO 之后添加空格,因此请打印一次查询并在外部 sqlite db 上运行它,以便您能够从查询中获取错误 成功了兄弟!! 很好,但始终注意查询中的空白插入

以上是关于Android SQLite NullPointer 异常和堆栈溢出异常 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在Android设备中用NDK编译SQLite并且对SQLite进行操作

Android--SQLite应用

反应原生 - SQLite - Android

Android 9 上的 android.database.sqlite.SQLiteCantOpenDatabaseException

Android开发之利用SQLite进行数据存储

Android-SQLite和SQLiteOpenHelper