Datenbank aufruf aus neuer Klasse?

  • Antworten:7
Max Power
  • Forum-Beiträge: 8

30.03.2014, 21:37:32 via Website

Hallo,

ich will aus einer anderen Klasse eine Datenbank aufrufen , einen Wert reinschreiben, und diesen Wert dann anzeigen lassen in einem Textfeld. Nur leider weiss ich nicht genau ob das so richtig ist bzw wie ich überhaupt aus einer neuen Klasse die DB aufrufen soll. Habe da zwar einige Examples nach gebaut, aber die funktionieren nur wenn Sie auch in der MainActivity sind nicht in einer neuen Klasse.

Der Inhalt der Datenbank ist noch leer. (Erstellt wurde Sie, aber ohne Werte in der mainTable)

Bin mir nicht sicher ob ich da überhaupt extends Activity nehmen muss? Wann muss ich denn immer extends Activity nehmen?

Danke schonmal vielmals

Hier mal der Code:

package com.example.test;

import android.app.Activity; import android.os.Bundle; import android.view.Menu;

public class MainActivity extends Activity {

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

   new Zugriff();

}





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

}

DatabaseAdapter:

// ------------------------------------ DBADapter.java ---------------------------------------------

// TODO: Change the package to match your project. package com.example.test;

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

// TO USE: // Change the package (at top) to match your project. // Search for "TODO", and make the appropriate changes. public class DBAdapter {

/////////////////////////////////////////////////////////////////////
//  Constants & Data
/////////////////////////////////////////////////////////////////////
// For logging:
private static final String TAG = "DBAdapter";

// DB Fields
public static final String KEY_ROWID = "_id";
public static final int COL_ROWID = 0;
/*
 * CHANGE 1:
 */
// TODO: Setup your fields here:
public static final String KEY_NAME = "name";
public static final String KEY_STUDENTNUM = "studentnum";
public static final String KEY_FAVCOLOUR = "favcolour";

// TODO: Setup your field numbers here (0 = KEY_ROWID, 1=...)
public static final int COL_NAME = 1;
public static final int COL_STUDENTNUM = 2;
public static final int COL_FAVCOLOUR = 3;


public static final String[] ALL_KEYS = new String[] {KEY_ROWID, KEY_NAME, KEY_STUDENTNUM, KEY_FAVCOLOUR};

// DB info: it's name, and the table we are using (just one).
public static final String DATABASE_NAME = "MyDb";
public static final String DATABASE_TABLE = "mainTable";
// Track DB version if a new version of your app changes the format.
public static final int DATABASE_VERSION = 2;   

private static final String DATABASE_CREATE_SQL = 
        "create table " + DATABASE_TABLE 
        + " (" + KEY_ROWID + " integer primary key autoincrement, "

        /*
         * CHANGE 2:
         */
        // TODO: Place your fields here!
        // + KEY_{...} + " {type} not null"
        //  - Key is the column name you created above.
        //  - {type} is one of: text, integer, real, blob
        //  - "not null" means it is a required field (must be given a value).
        // NOTE: All must be comma separated (end of line!) Last one must have NO comma!!
        + KEY_NAME + " text not null, "
        + KEY_STUDENTNUM + " integer not null, "
        + KEY_FAVCOLOUR + " string not null"

        // Rest  of creation:
        + ");";

// Context of application who uses us.
private final Context context;

private DatabaseHelper myDBHelper;
private SQLiteDatabase db;

/////////////////////////////////////////////////////////////////////
//  Public methods:
/////////////////////////////////////////////////////////////////////

public DBAdapter(Context ctx) {
    this.context = ctx;
    myDBHelper = new DatabaseHelper(context);
}

// Open the database connection.
public DBAdapter open() {
    db = myDBHelper.getWritableDatabase();
    return this;
}

// Close the database connection.
public void close() {
    myDBHelper.close();
}

// Add a new set of values to the database.
public long insertRow(String name, int studentNum, String favColour) {
    /*
     * CHANGE 3:
     */     
    // TODO: Update data in the row with new fields.
    // TODO: Also change the function's arguments to be what you need!
    // Create row's data:
    ContentValues initialValues = new ContentValues();
    initialValues.put(KEY_NAME, name);
    initialValues.put(KEY_STUDENTNUM, studentNum);
    initialValues.put(KEY_FAVCOLOUR, favColour);

    // Insert it into the database.
    return db.insert(DATABASE_TABLE, null, initialValues);
}

// Delete a row from the database, by rowId (primary key)
public boolean deleteRow(long rowId) {
    String where = KEY_ROWID + "=" + rowId;
    return db.delete(DATABASE_TABLE, where, null) != 0;
}

public void deleteAll() {
    Cursor c = getAllRows();
    long rowId = c.getColumnIndexOrThrow(KEY_ROWID);
    if (c.moveToFirst()) {
        do {
            deleteRow(c.getLong((int) rowId));              
        } while (c.moveToNext());
    }
    c.close();
}

// Return all data in the database.
public Cursor getAllRows() {
    String where = null;
    Cursor c =  db.query(true, DATABASE_TABLE, ALL_KEYS, 
                        where, null, null, null, null, null);
    if (c != null) {
        c.moveToFirst();
    }
    return c;
}

// Get a specific row (by rowId)
public Cursor getRow(long rowId) {
    String where = KEY_ROWID + "=" + rowId;
    Cursor c =  db.query(true, DATABASE_TABLE, ALL_KEYS, 
                    where, null, null, null, null, null);
    if (c != null) {
        c.moveToFirst();
    }
    return c;
}

// Change an existing row to be equal to new data.
public boolean updateRow(long rowId, String name, int studentNum, String favColour) {
    String where = KEY_ROWID + "=" + rowId;

    /*
     * CHANGE 4:
     */
    // TODO: Update data in the row with new fields.
    // TODO: Also change the function's arguments to be what you need!
    // Create row's data:
    ContentValues newValues = new ContentValues();
    newValues.put(KEY_NAME, name);
    newValues.put(KEY_STUDENTNUM, studentNum);
    newValues.put(KEY_FAVCOLOUR, favColour);

    // Insert it into the database.
    return db.update(DATABASE_TABLE, newValues, where, null) != 0;
}



/////////////////////////////////////////////////////////////////////
//  Private Helper Classes:
/////////////////////////////////////////////////////////////////////

/**
 * Private class which handles database creation and upgrading.
 * Used to handle low-level database access.
 */
private static class DatabaseHelper extends SQLiteOpenHelper
{
    DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase _db) {
        _db.execSQL(DATABASE_CREATE_SQL);           
    }

    @Override
    public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion) {
        Log.w(TAG, "Upgrading application's database from version " + oldVersion
                + " to " + newVersion + ", which will destroy all old data!");

        // Destroy old database:
        _db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);

        // Recreate new database:
        onCreate(_db);
    }
}

}

Und dann noch die Zugriffsklasse (Hier soll der Aufruf der Datenbank stattfinden)

package com.example.test;

import android.app.Activity; import android.database.Cursor; import android.widget.TextView;

public class Zugriff extends Activity{

DBAdapter myDb;

public Zugriff() {
openDB();   


long newId = myDb.insertRow("Jenny", 5559, "Green");

// Query for the record we just added.
// Use the ID:
Cursor cursor = myDb.getRow(newId);
displayRecordSet(cursor);

}

private void displayRecordSet(Cursor cursor) { String message = ""; // populate the message from the cursor

// Reset cursor to start, checking to see if there's data:
if (cursor.moveToFirst()) {
    do {
        // Process the data:
        int id = cursor.getInt(DBAdapter.COL_ROWID);
        String name = cursor.getString(DBAdapter.COL_NAME);
        int studentNumber = cursor.getInt(DBAdapter.COL_STUDENTNUM);
        String favColour = cursor.getString(DBAdapter.COL_FAVCOLOUR);

        // Append data to the message:
        message += "id=" + id
                   +", name=" + name
                   +", #=" + studentNumber
                   +", Colour=" + favColour
                   +"\n";
    } while(cursor.moveToNext());
}

// Close the cursor to avoid a resource leak.
cursor.close();

displayText(message);

} private void displayText(String message) { TextView textView = (TextView) findViewById(R.id.textDisplay); textView.setText(message); } @Override protected void onDestroy() { super.onDestroy();
closeDB(); }

private void openDB() { myDb = new DBAdapter(this); myDb.open(); } private void closeDB() { myDb.close(); }

}

Und LogCat sagt folgendes:

03-30 15:20:03.838: E/AndroidRuntime(784): FATAL EXCEPTION: main

03-30 15:20:03.838: E/AndroidRuntime(784): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test/com.example.test.MainActivity}: java.lang.NullPointerException 03-30 15:20:03.838: E/AndroidRuntime(784): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211) 03-30 15:20:03.838: E/AndroidRuntime(784): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261) 03-30 15:20:03.838: E/AndroidRuntime(784): at android.app.ActivityThread.access$600(ActivityThread.java:141) 03-30 15:20:03.838: E/AndroidRuntime(784): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 03-30 15:20:03.838: E/AndroidRuntime(784): at android.os.Handler.dispatchMessage(Handler.java:99) 03-30 15:20:03.838: E/AndroidRuntime(784): at android.os.Looper.loop(Looper.java:137) 03-30 15:20:03.838: E/AndroidRuntime(784): at android.app.ActivityThread.main(ActivityThread.java:5103) 03-30 15:20:03.838: E/AndroidRuntime(784): at java.lang.reflect.Method.invokeNative(Native Method) 03-30 15:20:03.838: E/AndroidRuntime(784): at java.lang.reflect.Method.invoke(Method.java:525) 03-30 15:20:03.838: E/AndroidRuntime(784): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 03-30 15:20:03.838: E/AndroidRuntime(784): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 03-30 15:20:03.838: E/AndroidRuntime(784): at dalvik.system.NativeStart.main(Native Method) 03-30 15:20:03.838: E/AndroidRuntime(784): Caused by: java.lang.NullPointerException 03-30 15:20:03.838: E/AndroidRuntime(784): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:235) 03-30 15:20:03.838: E/AndroidRuntime(784): at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224) 03-30 15:20:03.838: E/AndroidRuntime(784): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164) 03-30 15:20:03.838: E/AndroidRuntime(784): at com.example.test.DBAdapter.open(DBAdapter.java:88) 03-30 15:20:03.838: E/AndroidRuntime(784): at com.example.test.Zugriff.openDB(Zugriff.java:64) 03-30 15:20:03.838: E/AndroidRuntime(784): at com.example.test.Zugriff.(Zugriff.java:12) 03-30 15:20:03.838: E/AndroidRuntime(784): at com.example.test.MainActivity.onCreate(MainActivity.java:15) 03-30 15:20:03.838: E/AndroidRuntime(784): at android.app.Activity.performCreate(Activity.java:5133) 03-30 15:20:03.838: E/AndroidRuntime(784): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 03-30 15:20:03.838: E/AndroidRuntime(784): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175) 03-30 15:20:03.838: E/AndroidRuntime(784): ... 11 more

Denke mal aus der Klasse kann nicht richtig auf die Datenbank zugegriffen werden (Zugriff.openDB(Zugriff.java:64) deswegen die NullPointerException

DANKE !

— geändert am 30.03.2014, 21:49:07

Antworten
impjor
  • Forum-Beiträge: 1.793

30.03.2014, 21:58:12 via App

extends Activity darfst du nur benutzen, wenn die Klasse eine Activity ist, nur mit startActivity() aufgerufen wird und im Manifest eingetragen ist.

Bei deiner Zugriff-Klasse also verboten.
Wenn du nicht von Activity erbst, werden bestimmte Funktionen (die eines Contextes/Activity fehlen.
Stattdessen braucht deine Zugriff-Klasse ein Context-Objekt, das sie verwenden kann.

Bsp: in einer Activity-Klasse kann man ganz einfach startActivity(...) aufrufen. In einer Klasse, die nicht von Activity (bzw. Context) erbt, braucht man aber ein Objekt:
Activity ctx = ....;
ctx.startActivity(...);

Um ein Activity-Objekt zu bekommen, kann deine Zugriff-Klasse im Konstruktor ein Activity-Objekt verlangen.

Liebe Grüße impjor.

Für ein gutes Miteinander: Unsere Regeln
Apps für jeden Einsatzzweck
Stellt eure App vor!

Max Power

Antworten
Max Power
  • Forum-Beiträge: 8

30.03.2014, 22:12:15 via Website

Hi,
Danke für die Antwort.
Kann damit jetzt leider noch nicht so viel anfangen.
Kennst du irgendwelche Beispiel projekte wo das so ist?

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

31.03.2014, 06:51:49 via App

Schau mal im inet nach Konstruktoren
Da müsstest du eigentlich was finden.

LG Pascal //It's not a bug, it's a feature. :) ;)

Max Power

Antworten
AndreasP
  • Forum-Beiträge: 13

31.03.2014, 08:33:06 via Website

Also impjor und Pascal haben ja schon alles gesagt, damit solltest du nach etwas Recherche
eigentlich zurecht kommen.

Hier nochmal ein Ansatz mit Code:

in deiner MainActivity:
1@Override
2protected void onCreate(Bundle savedInstanceState) {
3 super.onCreate(savedInstanceState);
4 setContentView(R.layout.activity_main);
5
6 new Zugriff(this);
7
8}

und deine "Zugriff" muss jetzt einen Konstruktor haben:
1Activity activity;
2
3public Zugriff(Activity act)
4 {
5 this.activity = act;
6 }

Code ist nicht ganz vollständig, aber verdeutlicht das Prinzip.

Max Power

Antworten
Max Power
  • Forum-Beiträge: 8

31.03.2014, 18:00:53 via Website

Okay danke schonmal
schaue mal ob ich damit was anfangen kann ;-)


Ein Frage noch.

Rufe ich jetzt aus der Zugriffsklasse nur die Sachen aus dem Mainactivity auf?
Oder muss ich den ganzen Code in den Konstruktor der Zugriffs Klasse schreiben?

— geändert am 31.03.2014, 19:20:35

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

31.03.2014, 21:16:35 via App

Deine Zugriffsklasse soll ja die Arbeit erledigen. Du willst sie ja nur aus der main ansteuern und benutzen wie zb. daten übergeben.
Dann muss die Klasse alles zugehörige unterstüzen

LG Pascal //It's not a bug, it's a feature. :) ;)

Max Power

Antworten
Max Power
  • Forum-Beiträge: 8

31.03.2014, 21:49:05 via Website

Okay dann probiere ich das mal umzusetzen.
Habe zwar nich einen konkreten plan, aber muss mich wohl noch etwas schlau lesen

Antworten