-1

こんにちは、私のコードで挿入例外を見つけようとしています。開始する前に、文字列 EditText の挿入を開始します。最初に独自の文字列を挿入したかったのです。ただし、logcat からエラーが発生します。どちらも文字列型で、主キー行も自動インクリメントに設定されています。誰にもガイダンスはありますか。

データベース アクティビティ

private static class DbHelper extends SQLiteOpenHelper {

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

        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("CREATE TABLE " + DATABASE_TABLE +  " (" +
                        KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                        KEY_MODULECODE + " TEXT, " +
                        KEY_MODULENAME + " TEXT); "
                    );
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            // TODO Auto-generated method stub
            db.execSQL("DROP TABEL IF EXISTS " + DATABASE_TABLE);
            onCreate(db);
        }
    }

    public database(Context c){
        myContext = c;
    }

    public  database openToWrite()throws SQLException{
        myHelper = new DbHelper(myContext);
        moduleDatabase = myHelper.getWritableDatabase();
        return this;
    }

    public  database openToRead()throws SQLException{
        myHelper = new DbHelper(myContext);
        moduleDatabase = myHelper.getReadableDatabase();
        return this;
    }
    public void close(){
    myHelper.close();
    }

    public void createEntry(String moduleCode, String moduleName) throws SQLException {
        ContentValues cv = new ContentValues();
        cv.put(KEY_MODULECODE,moduleCode);
        cv.put(KEY_MODULENAME,moduleName);
        moduleDatabase.insert(DATABASE_TABLE,null,cv);
        // TODO Auto-generated method stub

    }

    public Cursor getData() {

        String[] columns = new String [] {KEY_ROWID,KEY_MODULECODE, KEY_MODULENAME};
        Cursor c = moduleDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);

        return c;
    }

}

主な活動

public class MyCourses extends Activity {

    static final String TEST = "com.example.mycoursetimetable.TEST";
    String [] MODULE;
    database MODULEDATABASE;  
    ListView listContent;
    Boolean didItWork;


    Cursor cursor;

        @Override
        public void onCreate(Bundle savedInstanceState) 
        {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_my_courses);

       listContent =(ListView)findViewById(R.id.list);
       MODULEDATABASE = new database(MyCourses.this);

       MODULEDATABASE.openToWrite();
       MODULEDATABASE.createEntry("TestCode", "TestName");
       MODULEDATABASE.close();

       MODULEDATABASE.openToRead();
       cursor = MODULEDATABASE.getData();
       MODULEDATABASE.close();

       listContent = (ListView)findViewById(R.id.list);

       TestCursorAdapter ca = new TestCursorAdapter(this, cursor, 0);

       listContent.setAdapter(ca);

        }

}

CursorAdapter

public class TestCursorAdapter extends CursorAdapter {

    private LayoutInflater viewInflater;
    boolean didItWork;

    public TestCursorAdapter(Context context, Cursor c, int flags) {
        super(context, c, flags);
        // TODO Auto-generated constructor stub
        viewInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public void bindView(View v, Context context, Cursor c) 
    {

        TextView text_modulecode = (TextView)v.findViewById(R.id.labelModuleCode);
        TextView text_modulename = (TextView)v.findViewById(R.id.labelEditModuleFull);

        text_modulecode.setText(String.valueOf(c.getColumnIndex(database.KEY_MODULECODE)));
        text_modulename.setText(String.valueOf(c.getColumnIndex(database.KEY_MODULENAME)));

    }

    @Override
    public View newView(Context context, Cursor c, ViewGroup parent) {
        View v = viewInflater.inflate(R.layout.listcourses, parent, false);
        return v;
    }

}

LogCat の 80 行目は、moduleDatabase.insert(DATABASE_TABLE,null,cv); を参照しています。

10-21 22:42:19.812: E/Database(19591): Error inserting module_name=TestName module_code=TestCode
10-21 22:42:19.812: E/Database(19591): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
10-21 22:42:19.812: E/Database(19591):  at android.database.sqlite.SQLiteStatement.native_execute(Native Method)
10-21 22:42:19.812: E/Database(19591):  at android.database.sqlite.SQLiteStatement.execute(SQLiteStatement.java:66)
10-21 22:42:19.812: E/Database(19591):  at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1426)
10-21 22:42:19.812: E/Database(19591):  at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1286)
10-21 22:42:19.812: E/Database(19591):  at com.example.mycoursetimetable.database.createEntry(database.java:80)
10-21 22:42:19.812: E/Database(19591):  at com.example.mycoursetimetable.MyCourses.onCreate(MyCourses.java:48)
10-21 22:42:19.812: E/Database(19591):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
10-21 22:42:19.812: E/Database(19591):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
10-21 22:42:19.812: E/Database(19591):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
10-21 22:42:19.812: E/Database(19591):  at android.app.ActivityThread.access$2200(ActivityThread.java:119)
10-21 22:42:19.812: E/Database(19591):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
10-21 22:42:19.812: E/Database(19591):  at android.os.Handler.dispatchMessage(Handler.java:99)
10-21 22:42:19.812: E/Database(19591):  at android.os.Looper.loop(Looper.java:123)
10-21 22:42:19.812: E/Database(19591):  at android.app.ActivityThread.main(ActivityThread.java:4363)
10-21 22:42:19.812: E/Database(19591):  at java.lang.reflect.Method.invokeNative(Native Method)
10-21 22:42:19.812: E/Database(19591):  at java.lang.reflect.Method.invoke(Method.java:521)
10-21 22:42:19.812: E/Database(19591):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
10-21 22:42:19.812: E/Database(19591):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
10-21 22:42:19.812: E/Database(19591):  at dalvik.system.NativeStart.main(Native Method)
10-21 22:42:19.862: E/Cursor(19591): Invalid statement in fillWindow()
4

1 に答える 1

2

カーソルエラーが発生しています:Invalid statement in fillWindow()データベースのセットアップが不安定なためです。実際にデータベースを2回閉じてから、閉じたデータベースをアタッチしたため、非アクティブなカーソルがリストビューに表示されましたが、正しくないようですか? 通常、ベスト プラクティスでは、カーソルを閉じてからデータベース オブジェクトを閉じます。この順序で閉じます。通常、クエリが完了したら、これらをどこにでも置くことができますが、カーソル アダプターに支えられたリストビューは特別です。リストビューが開いていてそれにアクセスしている間は常に、カーソルを開いて、配列オブジェクトやデータ コンテナーのようにデータ ソースを使用できるようにする必要があります。そうしないと、 というエラーが表示されますattempting to re-open an already-closed object。したがって、リストビューがとにかく根絶されている場合、それを配置するのに最適な場所は、imhoですonDestroy()

@Override
    protected void onDestroy() {
        super.onDestroy();
        cursor.close();
        MODULEDATABASE.close();

    }

ここで、同じアクティビティでデータベースの 2 つのインスタンスを開くことについて、いくつかの不満があることをお伝えしなければなりません。これを言うと反発を受けるかもしれませんが.getWritableDatabase().getReadableDatabase()実際には同じ接続を開き、それほど違いはありません. 1 つの接続を閉じて別の接続を開くというのは、賢明な方法のように思えますが、単に良い習慣ではありません。アプリから 1 つのメソッド (getReadable) を完全に削除する必要があると言っているわけではありませんが、同じアクティビティ ライフサイクルで両方を開くことはピーナッツをめぐって争っています。これは、アクティビティが行われている間ずっとカーソルを開いておく必要があることを確認したばかりなので、さらに真実です。必要なものとそうでないものについて話しているので、インスタンス化listContentを 2 回行っています。

説明が長くなって申し訳ありませんが、詳細が明確になっていることを確認したかったのです。

于 2012-11-02T20:16:20.987 に答える