2012-12-24 52 views
0

我把我的头从我的桌子上敲下来。我似乎无法弄清楚这一点。我想要做的就是在创建活动时使用来自SQLite数据库的项目填充listview。也许我错过了一些小事,我不知道在这一点上,我已经无法沮丧了。我知道数据库没有被创建,因为它不存在于文件资源管理器中。nullpointerexception和数据库没有被创建

这里是DatabaseHandler.java:

package com.dd.gfit; 

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

public class DatabaseHandler extends SQLiteOpenHelper { 

    private SQLiteDatabase db; 

    // database strings 
    public static final String DATABASE_NAME = "gfit.db"; 
    public static final int DATABASE_VERSION = 1; 

    // table strings 
    public static final String TABLE_ROUTINES = "routines"; 

    // key strings 
    public static final String KEY_ROUTINES_ID = "id"; 
    public static final String KEY_ROUTINES_NAME = "name"; 

    public DatabaseHandler(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 

     // create routines table 
     db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_ROUTINES + " (" 
        + KEY_ROUTINES_ID + " INTEGER PRIMARY KEY AUTO_INCREMENT," 
        + KEY_ROUTINES_NAME + " VARCHAR" 
        + ")"); 

     // insert test data into routines table 
     db.execSQL("INSERT INTO " + TABLE_ROUTINES + " (" + KEY_ROUTINES_NAME + ") VALUES ('Test Routine 1')"); 
     db.execSQL("INSERT INTO " + TABLE_ROUTINES + " (" + KEY_ROUTINES_NAME + ") VALUES ('Test Routine 2')"); 
     db.execSQL("INSERT INTO " + TABLE_ROUTINES + " (" + KEY_ROUTINES_NAME + ") VALUES ('Test Routine 3')"); 
     db.execSQL("INSERT INTO " + TABLE_ROUTINES + " (" + KEY_ROUTINES_NAME + ") VALUES ('Test Routine 4')"); 
     db.execSQL("INSERT INTO " + TABLE_ROUTINES + " (" + KEY_ROUTINES_NAME + ") VALUES ('Test Routine 5')"); 

    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     // do database upgrades here 
    } 

    public Cursor fetchRoutines() { 
     Cursor cursor = db.query(TABLE_ROUTINES, new String[] {KEY_ROUTINES_ID, KEY_ROUTINES_NAME}, null, null, null, null, null); 

     if (cursor != null) { 
      cursor.moveToFirst(); 
     } 

     return cursor; 
    } 

} 

这里是RoutinesActivity.java:

package com.dd.gfit; 

import android.os.Bundle; 
import android.app.Activity; 
import android.database.Cursor; 
import android.support.v4.app.NavUtils; 
import android.view.Menu; 
import android.view.MenuInflater; 
import android.view.MenuItem; 
import android.widget.ListAdapter; 
import android.widget.ListView; 
import android.widget.SimpleCursorAdapter; 

public class RoutinesActivity extends Activity { 

    private DatabaseHandler db = new DatabaseHandler(this); 
    private Cursor cursor = db.fetchRoutines(); 

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

     // Show the Up button in the action bar. 
     getActionBar().setDisplayHomeAsUpEnabled(true); 

     // open the database and show the routines 
     db.getWritableDatabase(); 
     displayRoutines(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     MenuInflater inflater = getMenuInflater(); 
     inflater.inflate(R.menu.activity_routines, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
     case android.R.id.home: 
      NavUtils.navigateUpFromSameTask(this); 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    private void displayRoutines() { 

     ListAdapter adapter = new SimpleCursorAdapter(
      this, 
      R.layout.listitem_routine, cursor, 
      new String[] { db.KEY_ROUTINES_NAME }, 
      new int[] { R.id.listitem_routine_name }); 

     ListView routineList = (ListView)findViewById(R.id.list_routines); 
     routineList.setAdapter(adapter); 
    } 

} 

这里是activity_routines.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context=".RoutinesActivity" > 

    <ListView 
     android:id="@+id/list_routines" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent"   
     android:layout_margin="10dp" > 

    </ListView> 

</RelativeLayout> 

这里是listitem_routine.xml:

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

    <TextView 
     android:id="@+id/listitem_routine_name" 
     android:layout_width="0dip" 
     android:layout_height="wrap_content" 
     android:layout_weight="1" 
     android:text="@string/lorem_routine_item" 
     android:textAppearance="?android:attr/textAppearanceMedium" /> 

    <ImageView 
     android:id="@+id/button_routine_edit" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:src="@drawable/ic_action_edit" 
     android:contentDescription="@string/ic_action_edit" /> 

    <ImageView 
     android:id="@+id/button_routine_delete" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:src="@drawable/ic_action_delete" 
     android:contentDescription="@string/ic_action_delete" /> 

</LinearLayout> 

这里有什么问题?另外,一旦我得到这个工作,每个listview项目中都有按钮,就像listitem_routine.xml所看到的那样。我想以某种方式将KEY_ROUTINES_ID传递给按钮,以便每个项目都可以随时编辑。有没有一个教程,我可以使用任何人都知道或可能只是一个片段?

编辑:

这里是日志:在下面的行

12-24 02:52:24.429: D/dalvikvm(783): GC_FOR_ALLOC freed 49K, 7% free 2564K/2732K, paused 68ms, total 69ms 
12-24 02:52:24.449: I/dalvikvm-heap(783): Grow heap (frag case) to 3.616MB for 1048592-byte allocation 
12-24 02:52:24.559: D/dalvikvm(783): GC_FOR_ALLOC freed 2K, 5% free 3585K/3760K, paused 110ms, total 110ms 
12-24 02:52:24.659: D/dalvikvm(783): GC_CONCURRENT freed <1K, 5% free 3585K/3760K, paused 5ms+3ms, total 102ms 
12-24 02:52:24.839: D/dalvikvm(783): GC_FOR_ALLOC freed <1K, 5% free 3585K/3760K, paused 51ms, total 51ms 
12-24 02:52:24.869: I/dalvikvm-heap(783): Grow heap (frag case) to 5.863MB for 2359312-byte allocation 
12-24 02:52:24.989: D/dalvikvm(783): GC_CONCURRENT freed 0K, 3% free 5889K/6068K, paused 24ms+33ms, total 115ms 
12-24 02:52:25.319: D/gralloc_goldfish(783): Emulator without GPU emulation detected. 
12-24 02:52:31.950: E/Trace(827): error opening trace file: No such file or directory (2) 
12-24 02:52:32.660: D/dalvikvm(827): GC_FOR_ALLOC freed 52K, 7% free 2564K/2736K, paused 25ms, total 28ms 
12-24 02:52:32.670: I/dalvikvm-heap(827): Grow heap (frag case) to 3.616MB for 1048592-byte allocation 
12-24 02:52:32.710: D/dalvikvm(827): GC_FOR_ALLOC freed 2K, 5% free 3585K/3764K, paused 40ms, total 40ms 
12-24 02:52:32.760: D/dalvikvm(827): GC_CONCURRENT freed <1K, 5% free 3585K/3764K, paused 5ms+3ms, total 50ms 
12-24 02:52:32.840: D/dalvikvm(827): GC_FOR_ALLOC freed <1K, 5% free 3585K/3764K, paused 19ms, total 19ms 
12-24 02:52:32.860: I/dalvikvm-heap(827): Grow heap (frag case) to 5.863MB for 2359312-byte allocation 
12-24 02:52:33.000: D/dalvikvm(827): GC_CONCURRENT freed 0K, 4% free 5889K/6072K, paused 77ms+13ms, total 140ms 
12-24 02:52:33.250: D/gralloc_goldfish(827): Emulator without GPU emulation detected. 
12-24 02:52:36.120: D/AndroidRuntime(827): Shutting down VM 
12-24 02:52:36.140: W/dalvikvm(827): threadid=1: thread exiting with uncaught exception (group=0x40a70930) 
12-24 02:52:36.190: E/AndroidRuntime(827): FATAL EXCEPTION: main 
12-24 02:52:36.190: E/AndroidRuntime(827): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.dd.gfit/com.dd.gfit.RoutinesActivity}: java.lang.NullPointerException 
12-24 02:52:36.190: E/AndroidRuntime(827): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2106) 
12-24 02:52:36.190: E/AndroidRuntime(827): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 
12-24 02:52:36.190: E/AndroidRuntime(827): at android.app.ActivityThread.access$600(ActivityThread.java:141) 
12-24 02:52:36.190: E/AndroidRuntime(827): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 
12-24 02:52:36.190: E/AndroidRuntime(827): at android.os.Handler.dispatchMessage(Handler.java:99) 
12-24 02:52:36.190: E/AndroidRuntime(827): at android.os.Looper.loop(Looper.java:137) 
12-24 02:52:36.190: E/AndroidRuntime(827): at android.app.ActivityThread.main(ActivityThread.java:5039) 
12-24 02:52:36.190: E/AndroidRuntime(827): at java.lang.reflect.Method.invokeNative(Native Method) 
12-24 02:52:36.190: E/AndroidRuntime(827): at java.lang.reflect.Method.invoke(Method.java:511) 
12-24 02:52:36.190: E/AndroidRuntime(827): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
12-24 02:52:36.190: E/AndroidRuntime(827): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
12-24 02:52:36.190: E/AndroidRuntime(827): at dalvik.system.NativeStart.main(Native Method) 
12-24 02:52:36.190: E/AndroidRuntime(827): Caused by: java.lang.NullPointerException 
12-24 02:52:36.190: E/AndroidRuntime(827): at com.dd.gfit.DatabaseHandler.fetchRoutines(DatabaseHandler.java:51) 
12-24 02:52:36.190: E/AndroidRuntime(827): at com.dd.gfit.RoutinesActivity.<init>(RoutinesActivity.java:17) 
12-24 02:52:36.190: E/AndroidRuntime(827): at java.lang.Class.newInstanceImpl(Native Method) 
12-24 02:52:36.190: E/AndroidRuntime(827): at java.lang.Class.newInstance(Class.java:1319) 
12-24 02:52:36.190: E/AndroidRuntime(827): at android.app.Instrumentation.newActivity(Instrumentation.java:1054) 
12-24 02:52:36.190: E/AndroidRuntime(827): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2097) 
12-24 02:52:36.190: E/AndroidRuntime(827): ... 11 more 
+0

忘记上传最重要的信息,即日志。 – wtsang02

+0

现在更新我的日志OP。 – scarhand

+0

@scarhand:帮你一个忙......在你的'Activity'中,你把'DatabaseHandler'命名为'db',但在代码的其他地方使用'db'来表示一个实际的数据库。将'DatabaseHandler'实例重命名为dbh或db以外的任何其他实例。 – Squonk

回答

1
private DatabaseHandler db = new DatabaseHandler(this); 
private Cursor cursor = db.fetchRoutines(); 

你不能把这个,因为它没有叫onCreate()呢。 db.fetchRoutines();会从您的数据库调用某些东西。但是你已经创建了你的数据库对象。 'this'不能被使用,因为对象没有构造。

private DatabaseHandler db = null; 
    private Cursor cursor = null; 
@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_routines); 

     // Show the Up button in the action bar. 
     getActionBar().setDisplayHomeAsUpEnabled(true); 

     // open the database and show the routines 
     db = new DatabaseHandler(this); 
     db.getWritableDatabase(); 

     cursor = db.fetchRoutines(); 
     displayRoutines(); 
    } 

这种方法

db = new DatabaseHandler(this); 

是你创建的对象。

db.getWritableDatabase(); 

是你得到你的数据库的地方,你只能在这行之后使用db操作。

+0

我如何正确地调用的OnCreate的数据库处理器?这一定是问题所在。它不调用创建,因此不创建数据库。 – scarhand

+0

有什么办法,我可以做到这一点没有做上面的onCreate空声明()?或者,我必须这样做,这样使得它可以在类的其他功能中使用? – scarhand

+0

另一种方式是传递引用其它功能参数,可以但设置它们为null声明似乎更容易。 – wtsang02

1

this关键字对您的崩溃的原因。 您在创建对象之前使用'this'关键字。

private DatabaseHandler db = new DatabaseHandler(this); 

执行以下操作

private DatabaseHandler db; 


    @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_routines); 
    db = new DatabaseHandler(this); 

     } 

而且下面一行移动到的onCreate()

private Cursor cursor = db.fetchRoutines(); 
1

DatabaseHandler中,您从不指定db的值。所以,当你在fetchRoutines()中调用db.query()时,它会崩溃。

你需要设置你的db成员变量,这样就可以在以后使用它。将以下行添加到DatabaseHandler.onCreate()的末尾:

this.db = db;