Android中SQLite构造函数参数Context的几点注意事项

来源:互联网 发布:js div添加内容 编辑:程序博客网 时间:2024/04/26 21:53

最近在写一个Android的程序,用到了SQLite数据库,在主项目中刚开始使用sqlite之前,我先在单独的一个项目中测试了一下SQLite的使用,只有一个Activity,一个SQLiteHelper,使用的时候好好的,当我在主项目中使用的时候就报错了,总是空指针错误,纠结了几天之后终于搞定了,现在我写出来,希望能帮到遇到同样问题的朋友们!

我的测试项目:

结构图:


DBHleper类代码:

package com.avin.android;import android.content.ContentValues;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;import android.util.Log;public class DBHelper extends SQLiteOpenHelper {public static final int VERSION = 1;/** * 作为SQLiteOpenHelper子类必须有的构造方法 * @param context * @param name 数据库名字 * @param factory * @param version */public DBHelper(Context context, String name, CursorFactory factory,int version) {super(context, name, factory, version);Log.d("Avin","this is dbhelper 4 elements");// TODO Auto-generated constructor stub}public DBHelper(Context context,String name, int version){this(context,name,null,version);Log.d("Avin","this is dbhelper 3 elements");}public DBHelper(Context context,String name){this(context,name,VERSION);Log.d("Avin","this is dbhelper 2 elements");}@Override/** * 第一次创建数据库的时候调用,而且是得到readableDatabase或者writeDatabase时才执行 */public void onCreate(SQLiteDatabase db) {// TODO Auto-generated method stubdb.execSQL("create table floats(id integer primary key autoincrement ,flt_cand text not null ,flt_key text)");Log.d("Avin","floats created...");}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// TODO Auto-generated method stub}}


SQLiteActivityHelper代码:

package com.avin.android;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.content.ContentValues;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.os.Bundle;import android.util.Log;public class SqliteActivity extends Activity {    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                DBHelper helper = new DBHelper(SqliteActivity.this,"sqlite.db");        Log.d("Avin","this is onCreate in SqliteActivity...the helper is -->"+helper);        SQLiteDatabase sdb = helper.getReadableDatabase();                Log.d("Avin","this is onCreate in SqliteActivity...the sdb is -->"+sdb);        sdb = helper.getWritableDatabase();        //如果不指定主键 会正常运行吗          //试试证明,会!                //批量插入        String[] cands = {"a","b","c","d"};        String[] keys = {"1","2","3","4"};                for(int i=0; i<cands.length; i++){        ContentValues cv = new ContentValues();        cv.put("flt_cand", cands[i]);        cv.put("flt_key", keys[i]);                sdb.insert("floats", null, cv);        }                Log.d("Avin","insert...");sdb.close();sdb = helper.getReadableDatabase();Cursor cur = sdb.query("floats", new String[]{"flt_cand"}, "flt_key=?", new String[]{"4"}, null, null, null);   while(cur.moveToNext()){String rst = cur.getString(cur.getColumnIndex("flt_cand"));Log.d("Avin", rst);}        }}

AndroidManifest.xml文件:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.avin.android"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk android:minSdkVersion="8" />    <application        android:icon="@drawable/ic_launcher"        android:label="@string/app_name" >        <activity            android:name=".SqliteActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>


源代码如上面贴出来的,在SQLiteActivity的OnCreate方法中初始化DBHelper的对象,把SQLiteActivity.this作为Oncreate的参数Context传递进去,能正确初始化,

在我的项目中(要用到SQLite)的项目中,我把一个DBHelper封装进另外一个SQLiteOperator中使用,类似在DAO中使用数据库的链接一样,因为DBHelper的构造参数需要一个context类型的参数,问题就是这个Context类型的参数到底是谁的引用,开始我把这个SQLiteOperator(继承自Activity)传递给DBHelper的构造参数

DBHelper helper = new DBHelper(SqliteOperator.this,"sqlite.db"); 这样不行,报错 NullPointerException,后来我对照上面那个能正常运行的SQLite的初始化过程,发现上面的Context是一个能够正常显示的Activity,也就是说,DBHelper的构造方法使在SQLiteActivity的onCreate()方法中被调用的,而我这个报错的Activity并没用在它的onCreate()方法调用DBHelper的构造方法,所以我把SQLiteOperator添加了onCreate方法,然后仿照上面那样,调用DBHelper的构造,传递SQLiteOperator.this当做Context,不行,还是空指针!
没办法,自习对比发现,是不是DBHelper的构造必须要在一个能显示的Activity的onCreate中调用才可以! 我在我的MainActivity的onCreate()方法中传递MainActivity.this当做Context来初始化DBHelper的对象,搞定!
总结:Android项目中实现SQLiteOpenHelper的那个类的初始化必须在一个能正常显示的Activity的OnCreate方法中调用,而且,必须要用这个Activity的this引用当做Context才能正常构建SQLite数据库,这个Contex即使是一个Activity但是在程序中没用界面,也不能把这个Activity的引用当做Context来构建数据库,这样只会报莫名的空指针!

原创粉丝点击