我是Android框架的新手,我无法通过SQLite获得第一个基础。
我正在尝试构建一个非常简单的应用程序,它有一个EditText搜索框,当按下某个键时,会在SQLite数据库上执行Like%word%搜索,以获取在EditText框中输入的文本,并显示得到一个ListView。
N.B。下面的代码包括调试和注释代码,对不起,我还没有完成清理它。
激活是
public class sustainable_fish extends Activity {
private String keycodeToAscii(int arg2){
String retvar = "";
switch(arg2){
case KeyEvent.KEYCODE_A: retvar = "a";break;
case KeyEvent.KEYCODE_B: retvar = "b";break;
剪断,但你明白了。
case KeyEvent.KEYCODE_RIGHT_BRACKET: retvar = ")";break;
default: retvar = ""; break;
};
return retvar;
}
Context that = getApplicationContext();
fishDB dh = new fishDB(getApplicationContext());
private OnKeyListener search = new OnKeyListener() {
public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
@SuppressWarnings("unused")
Cursor cur = null;
String searchData;
EditText myEditText = (EditText) findViewById(R.id.fish_search);
CharSequence edit_text_value = myEditText.getText();
searchData = edit_text_value.toString();
searchData = searchData + keycodeToAscii(arg2.getKeyCode() );
Log.d("onKey", "searchData = "+searchData);
/*
Commented out because as the database doesn't work, so theirs no point just yet searching.
cur = fish.search(searchData);
if (cur != null)
{
String[] displayFields = new String[] {cur.getString(2),
cur.getString(1)};
int[] displayViews = new int[] { R.id.fish_rank,
R.id.fish_name};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(that,
R.layout.text_list, cur,
displayFields, displayViews);
ListView myList=(ListView)findViewById(android.R.id.list);
myList.setAdapter(adapter);
}
*/
return false;
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
EditText searchBar = (EditText) findViewById(R.id.fish_search);
searchBar.setOnKeyListener(search);
}
}
SQLite数据库由fishDB处理
public class fishDB {
public static final String DATABASE_NAME = "fish.db3";
public static final int DATABASE_VERSION = 1;
private SQLiteDatabase database;
private Context myContext;
private static boolean booFirstrun = false;
fishDB(Context inContext){
myContext = inContext;
OpenHelper helper = new OpenHelper(myContext);
Log.w("fishDB", "Called OpenHelper");
// Here be the problem...
database = helper.getWritableDatabase();
}
public boolean firstRun(){
return booFirstrun;
}
private static class OpenHelper extends SQLiteOpenHelper {
private static final String CREATE_TABLE_FEEDS = "create table feeds (feed_id integer primary key autoincrement, "
+ "title text not null, url text not null);";
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
Log.w("OpenHelper", "Called superconstructor");
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
Log.w("OpenHelper", "in onCreate");
booFirstrun = true;
Log.w("OpenHelper", "set booFirstrun");
db.beginTransaction();
Log.w("OpenHelper", "db.beginTransaction");
try {
// Create tables and test data
db.execSQL(CREATE_TABLE_FEEDS);
Log.w("OpenHelper", "execSQL");
db.setTransactionSuccessful();
Log.w("OpenHelper", "setTransactionSuccessful");
} catch (SQLException e) {
Log.e("Error creating tables and debug data", e.toString());
throw e;
} finally {
db.endTransaction();
}
} catch (Exception e) {
Log.e("OpenHelper", e.toString() );
} finally {
Log.w("OpenHelper", "out of onCreate");
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w("OpenHelper", "Upgrading database, this will drop tables and recreate.");
onCreate(db);
}
}
}
现在每次“database = helper.getWritableDatabase();”被称为应用程序崩溃与NullPointerException。我设法将错误跟踪到OpenHelper的onCreate方法和“db.beginTransaction();”线。
我错过了什么?
答案 0 :(得分:8)
实际上,您不需要在帮助程序的onCreate方法上启动事务。尝试从db.execSQL(CREATE_TABLE_FEEDS);
更新:我能够重复此问题。
在该错误消失后,将fishDb字段初始化移至onCreate()
活动方法。看起来在调用onCreate之前启动数据库初始化并不是一个好主意。
所以而不是
fishDB fishDb = new fishDB(getApplicationContext());
DO
fishDB fishDb;
onCreate(){
super.onCreate();
fishDb = new fishDB(getApplicationContext());
.... //init listener, query db etc..
}
答案 1 :(得分:2)
以下代码源自最初的Android NotePad教程:
public class FishDb {
private static final String TAG = "FishDb";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
private static final String CREATE_TABLE_FEEDS = "create table feeds (_id integer primary key autoincrement, "
+ "title text not null, url text not null);";
public static final String DATABASE_NAME = "fish.db3";
public static final String DATABASE_TABLE = "feeds";
private static final int DATABASE_VERSION = 1;
private final Context mCtx;
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_FEEDS);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS feeds");
onCreate(db);
}
}
public DbAdapter(Context ctx) {
this.mCtx = ctx;
}
public DbAdapter open() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}
public void close() {
mDbHelper.close();
}
// ... The helper methods
}
您可以在onCreate()中实例化实例化,并在onPesume()上打开on(),在onPause()上关闭():
private FishDb mDbHelper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDbHelper = new FishDb(this);
}
@Override
public void onResume() {
super.onResume();
try{
mDbHelper.open();
} catch(Exception e){
Log.e("onResume", e.toString());
}
}
@Override
public void onPause() {
super.onPause();
try{
mDbHelper.close();
} catch(Exception e){
Log.e("onPause", e.toString());
}
}
希望有所帮助。
编辑:使用“_id”而不是“feed_id”作为主键。