2010-07-22 10 views
0

J'ai quatre onglets (rapports, rapports d'examen, carte et paramètres). J'ai une base de données sqlite remplie avec des informations de rapport. Je souhaite avoir la base de données accessible tout au long de l'application. L'onglet Rapports ajoute des données à la base de données, mais en utilisant la même méthode, l'application est bloquée. Le débogueur Android pointe vers la ligne où la base de données est à nouveau appelée.Accès à la base de données Android sur plusieurs onglets

Dans l'onglet rapports, le code suivant est utilisé pour lancer la base de données ...

this.reportDatabase = new ReportDatabase(this); 
    this.reportDatabase.insert("(" + latitude + ", " + longitude + ", " + time + ", '" + spinnerState + "', " + lower + ", " + upper + ", " + agreed + ", " + getAlgorithmCount() + ", " + xAxis + ", " + yAxis + ", " + zAxis + ", " + altitude + ", "+ accuracy + ", 'photo');"); 

Dans la méthode onCreate() de l'onglet Révision - Où je souhaite examiner les rapports - j'essaie d'accéder à la base de données via l'appel appelant la méthode de rapport de retour

this.reportDatabase = new ReportDatabase (this);

Cependant, cela ne fonctionne pas. Dans le débogueur android souligne que le problème appartient au contexte qui lui est fourni. Je me rends compte que la base de données du rapport a déjà été accédée par l'onglet du rapport et je me demande si cela cause le problème. Je suis nouveau à la programmation android, l'application est conçue pour rendre compte sur les flamants roses en Afrique, toute aide serait grandement appréciée!

Suite à la suggestion de Seva Alexeïev, je me suis adapté comme suit ...

J'ai adapté mon ReportDatabase comme ...

public ReportDatabase(Context context) { 
    super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    ReportDatabase.context = context; 
    OpenHelper openHelper = new OpenHelper(ReportDatabase.context); 
    this.database = openHelper.getWritableDatabase(); 
} 

static ReportDatabase open(Context c){ 
    if(reportDatabase == null){ 
    reportDatabase = new ReportDatabase(ReportDatabase.context); 
    return reportDatabase; 
    } 
    return reportDatabase; 
} 

en utilisant ...

reportDatabase = ReportDatabase.open(this); 

Comme l'appel dans l'onglet de rapport et de révision. Malheureusement cela ne semble pas fonctionner, le débogueur s'arrête sur la même méthode. Le fichier ReportDatabase.java complet est ici ...

package com.android.flamingo; 

import java.util.Vector; 

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

public class ReportDatabase extends SQLiteOpenHelper { 
private static Context context; 
private SQLiteDatabase database; 

static ReportDatabase reportDatabase; 

private static final String DATABASE_NAME = "flamingo_reports"; 
private static final int DATABASE_VERSION = 1; 
private static final String TABLE_NAME = "reports"; 

/** 
* Default (and only) constructor.... 
* 
* @param context 
*/ 

public ReportDatabase(Context context) { 
    super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    ReportDatabase.context = context; 
    OpenHelper openHelper = new OpenHelper(ReportDatabase.context); 
    this.database = openHelper.getWritableDatabase(); 
} 

static ReportDatabase open(Context c){ 
    if(reportDatabase == null){ 
     reportDatabase = new ReportDatabase(ReportDatabase.context); 
     return reportDatabase; 
    } 
    return reportDatabase; 
} 

/** 
* 
* @param name 
*/ 

public void insert(String name){ 
    this.database.execSQL("INSERT INTO " + TABLE_NAME + "(latitude, longitude, time, lake, lower_estimate, higher_estimate, agreed_estimate, algorithm_count, xaxis, yaxis, zaxis, altitude, accuracy, photo_identifier) VALUES " + name); 
} 

/** 
* This method returns a double array and probably shouldn't be this hacky... 
* 
* 
* @return 
*/ 

public Vector<ReportInstanceQuery> reportSelect(){ 
    Vector<ReportInstanceQuery> tempReports = new Vector<ReportInstanceQuery>(); 

    Cursor c = database.rawQuery("SELECT id,time,lake,lower_estimate,higher_estimate,agreed_estimate,algorithm_count FROM" + TABLE_NAME + ";",null); 
    int indexTime = c.getColumnIndex("time"); 
    int indexLake = c.getColumnIndex("lake"); 
    int indexLowerEstimate = c.getColumnIndex("lower_estimate"); 
    int indexHigherEstimate = c.getColumnIndex("higher_estimate"); 
    int indexAgreedEstimate = c.getColumnIndex("agreed_estimate"); 
    int indexAlgorithmCount = c.getColumnIndex("algorithm_count"); 


    if (c != null){ 
     int i = 0; 
     do { 
      i++; 
      int columnTime = c.getInt(indexTime); 
      String columnLake = c.getString(indexLake); 
      int columnLowerEstimate = c.getInt(indexLowerEstimate); 
      int columnHigherEstimate = c.getInt(indexHigherEstimate); 
      int columnAgreedEstimate = c.getInt(indexAgreedEstimate); 
      int columnAlgorithmCount = c.getInt(indexAlgorithmCount); 

      tempReports.add(new ReportInstanceQuery(columnTime, columnLake, columnLowerEstimate, columnHigherEstimate, columnAgreedEstimate, columnAlgorithmCount)); 
     } while (c.moveToNext()); 
    } 
    reportDatabase.close(); 
    return tempReports; 
} 

/** 
* This method connects to the database 
* 
*/ 

public void CSVReportSelect(){ 

} 

public void delete(){ 
    this.database.delete(TABLE_NAME, null, null); 
} 

@Override 
public void onCreate(SQLiteDatabase database) {   
} 

@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
} 


private static class OpenHelper extends SQLiteOpenHelper { 

    OpenHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 
    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.execSQL("CREATE TABLE " + TABLE_NAME + "(id INTEGER PRIMARY KEY AUTOINCREMENT, latitude REAL, longitude REAL, time INTEGER, lake TEXT, lower_estimate INTEGER, higher_estimate INTEGER, agreed_estimate INTEGER, algorithm_count INTEGER, xaxis REAL, yaxis REAL, zaxis REAL, altitude REAL, accuracy REAL, photo_identifier TEXT)"); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     Log.w("Example", "Upgrading database, this will drop tables and recreate."); 
     db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); 
     onCreate(db); 
    } 
} 

}

Avec la pile d'erreur étant ...

ReportDatabase.<init>(Context) line: 29 
ReportDatabase.open(Context) line: 37 
ReviewTab.onCreate(Bundle) line: 26 
Instrumentation.callActivityOnCreate(Activity, Bundle) line: 1123 
ActivityThread.performLaunchActivity(ActivityThread$ActivityRecord) line: 2231 
ActivityThread.startActivityNow(Activity, String, Intent, ActivityInfo, IBinder, Bundle, Object) line: 2112 
LocalActivityManager.moveToState(LocalActivityManager$LocalActivityRecord, int) line: 130 
LocalActivityManager.startActivity(String, Intent) line: 342  
TabHost$IntentContentStrategy.getContentView() line: 600  
TabHost.setCurrentTab(int) line: 310  
TabHost$2.onTabSelectionChanged(int, boolean) line: 126 
TabWidget$TabClickListener.onClick(View) line: 268 
RelativeLayout(View).performClick() line: 2183 
RelativeLayout(View).onTouchEvent(MotionEvent) line: 3849 
RelativeLayout(View).dispatchTouchEvent(MotionEvent) line: 3389 
RelativeLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 831 
TabWidget(ViewGroup).dispatchTouchEvent(MotionEvent) line: 863 
LinearLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 863 
TabHost(ViewGroup).dispatchTouchEvent(MotionEvent) line: 863  
FrameLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 863  
LinearLayout(ViewGroup).dispatchTouchEvent(MotionEvent) line: 863 
PhoneWindow$DecorView(ViewGroup).dispatchTouchEvent(MotionEvent) line: 863 
PhoneWindow$DecorView.superDispatchTouchEvent(MotionEvent) line: 1707 
PhoneWindow.superDispatchTouchEvent(MotionEvent) line: 1197 
HelloFlamingos(Activity).dispatchTouchEvent(MotionEvent) line: 1993 
PhoneWindow$DecorView.dispatchTouchEvent(MotionEvent) line: 1691  
ViewRoot.handleMessage(Message) line: 1525 
ViewRoot(Handler).dispatchMessage(Message) line: 99 
Looper.loop() line: 123 
ActivityThread.main(String[]) line: 3948  
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method] 
Method.invoke(Object, Object...) line: 521 
ZygoteInit$MethodAndArgsCaller.run() line: 782 
ZygoteInit.main(String[]) line: 540 
NativeStart.main(String[]) line: not available [native method] 

Idées?

+0

pouvons-nous voir une trace de pile? Android peut être difficile à déboguer et voir les erreurs verbatim peut aider. En outre, est-ce la classe ReportDatabase complète? – chrisbunney

+0

Le problème peut-il être que je ne ferme pas la base de données? –

+0

Eventuellement, avez-vous essayé de fermer la base de données lorsque vous avez fini de l'utiliser? Qu'y a-t-il aux lignes 29 et 37? – chrisbunney

Répondre

1

Vous essayez d'ouvrir la base de données plusieurs fois. Utilisez un objet ReportDatabase unique, disponible via une méthode statique ReportDatabase. Quelque chose comme ceci:

class ReportDatabase 
{ 
    static ReportDatabase TheDatabase = null; 

    static ReportDatabase Open(Context c) 
    { 
     if(TheDatabase == null) 
      TheDatabase = new ReportDatabase(c); 
     return TheDatabase; 
    } 
} 

Ceci est souvent appelé un singleton. Ou un global :)

+0

J'ai essayé, et ça ne marche pas, avez-vous d'autres suggestions? –

+0

Etes-vous sûr d'utiliser ReportDatabase.open() dans toute l'application? Envisagez de rendre le constructeur privé pour vérifier. S'il y a des appels constructeurs, ils deviendront des erreurs de compilation. –

Questions connexes