2012-08-06 2 views
0

Я пытаюсь использовать DB SQLite в своем приложении, и у меня возникают проблемы. Android возвращает сообщение об ошибке «принудительное закрытие», когда я пытаюсь запустить приложение, я проверил код, чтобы убедиться, что значения и значения в порядке и, похоже, сделаны, были сделаны некоторые отладки, и проблема явно на createDataBase метод. Ему нужно найти расположение БД, я прошел переменную PATH и даже все еще сбой, не знаю, правильно ли запускать прямо на планшете, мне нужно сделать другой путь, например данные/данные. ... (обнаружил, что исследование, не уверен) и на AVD (вот в чем проблема) мне нужно указать, где находится БД на моем рабочем столе?Запуск SQLite в AVD

взглянуть на код:

ConnectDB

package com.victor.profile; 

import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 

import android.app.Dialog; 
import android.content.Context; 
import android.database.SQLException; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteException; 
import android.database.sqlite.SQLiteOpenHelper; 
import com.victor.profile.MainActivity; 

public class ConnectDB extends SQLiteOpenHelper{ 

    //The Android's default system path of your application database. 
    private static String DB_PATH = "C:/Users/Victor/Dropbox/workspace/Profile/database"; 

    private static String DB_NAME = "profile_db"; 

    private SQLiteDatabase myDataBase; 

    private final Context myContext; 

    Dialog dialog; 

    boolean dbalert; 

    /** 
    * Constructor 
    * Takes and keeps a reference of the passed context in order to access to the application assets and resources. 
    * @param context 
    */ 
    public ConnectDB(Context context) { 

     super(context, DB_NAME, null, 1); 
     this.myContext = context; 
    } 

    /** 
    * Creates a empty database on the system and rewrites it with your own database. 
    * */ 
    public void createDataBase() throws IOException{ 

     boolean dbExist = checkDataBase(); 

     if(dbExist){ 
      //do nothing - database already exist 
     }else{ 

      //By calling this method and empty database will be created into the default system path 
       //of your application so we are gonna be able to overwrite that database with our database. 
      this.getReadableDatabase(); 

      try { 

       copyDataBase(); 

      } catch (IOException e) { 

       throw new Error("Error copying database"); 

      } 
     } 

    } 

    /** 
    * Check if the database already exist to avoid re-copying the file each time you open the application. 
    * @return true if it exists, false if it doesn't 
    */ 
    private boolean checkDataBase(){ 

     SQLiteDatabase checkDB = null; 

     try{ 
      String myPath = DB_PATH + DB_NAME; 
      checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 

     }catch(SQLiteException e){ 

      dbalert = new MainActivity().dbFail(); 

     } 

     if(checkDB != null){ 

      checkDB.close(); 

     } 

     return checkDB != null ? true : false; 
    } 

    /** 
    * Copies your database from your local assets-folder to the just created empty database in the 
    * system folder, from where it can be accessed and handled. 
    * This is done by transfering bytestream. 
    * */ 
    private void copyDataBase() throws IOException{ 

     //Open your local db as the input stream 
     InputStream myInput = myContext.getAssets().open(DB_NAME); 

     // Path to the just created empty db 
     String outFileName = DB_PATH + DB_NAME; 

     //Open the empty db as the output stream 
     OutputStream myOutput = new FileOutputStream(outFileName); 

     //transfer bytes from the inputfile to the outputfile 
     byte[] buffer = new byte[1024]; 
     int length; 
     while ((length = myInput.read(buffer))>0){ 
      myOutput.write(buffer, 0, length); 
     } 

     //Close the streams 
     myOutput.flush(); 
     myOutput.close(); 
     myInput.close(); 

    } 

    public void openDataBase() throws SQLException{ 

     //Open the database 
     String myPath = DB_PATH + DB_NAME; 
     myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); 

    } 

    @Override 
    public synchronized void close() { 

      if(myDataBase != null) 
       myDataBase.close(); 

      super.close(); 

    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 

    } 

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

    } 


     // Add your public helper methods to access and get content from the database. 
     // You could return cursors by doing "return myDataBase.query(....)" so it'd be easy 
     // to you to create adapters for your views. 

MainActivity

package com.victor.profile; 

import java.io.IOException; 

import android.app.Activity; 
import android.app.AlertDialog; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.View; 

public class MainActivity extends Activity { 


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

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.activity_main, menu); 
     return true; 
    } 

    public void onDestroy(){ 
     System.exit(0); 
    } 

    public void RegisterActivity(View view) throws IOException{ 

     Intent intent = new Intent (this, RegisterActivity.class); 
     ConnectDB dbcreator = new ConnectDB(this); 
     dbcreator.createDataBase(); 
     startActivity(intent); 
    } 



    public boolean dbFail(){ 
     AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create(); 
     alertDialog.setTitle("Closing App"); 
     alertDialog.setMessage("Unable to find Database..."); 
     alertDialog.setButton("OK", new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int which) { 
       onDestroy(); 
      } 
     }); 
     alertDialog.show(); 
     return true; 
    } 

} 

Вот это LogCat erros

08-06 17:44:09.915: I/Database(283): sqlite returned: error code = 14, msg = cannot open file at source line 25467 
*08-06 17:44:09.915: E/Database(283): sqlite3_open_v2("profile_db", &handle, 1, NULL) failed* 
08-06 17:44:09.925: D/AndroidRuntime(283): Shutting down VM 
08-06 17:44:09.925: W/dalvikvm(283): threadid=1: thread exiting with uncaught exception (group=0x4001d800) 
*08-06 17:44:09.946: E/AndroidRuntime(283): FATAL EXCEPTION: main 
08-06 17:44:09.946: E/AndroidRuntime(283): java.lang.IllegalStateException: Could not execute method of the activity 
08-06 17:44:09.946: E/AndroidRuntime(283): at android.view.View$1.onClick(View.java:2072) 
08-06 17:44:09.946: E/AndroidRuntime(283): at android.view.View.performClick(View.java:2408) 
08-06 17:44:09.946: E/AndroidRuntime(283): at android.view.View$PerformClick.run(View.java:8816) 
08-06 17:44:09.946: E/AndroidRuntime(283): at android.os.Handler.handleCallback(Handler.java:587) 
08-06 17:44:09.946: E/AndroidRuntime(283): at android.os.Handler.dispatchMessage(Handler.java:92) 
08-06 17:44:09.946: E/AndroidRuntime(283): at android.os.Looper.loop(Looper.java:123) 
08-06 17:44:09.946: E/AndroidRuntime(283): at android.app.ActivityThread.main(ActivityThread.java:4627) 
08-06 17:44:09.946: E/AndroidRuntime(283): at java.lang.reflect.Method.invokeNative(Native Method) 
08-06 17:44:09.946: E/AndroidRuntime(283): at java.lang.reflect.Method.invoke(Method.java:521) 
08-06 17:44:09.946: E/AndroidRuntime(283): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
08-06 17:44:09.946: E/AndroidRuntime(283): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
08-06 17:44:09.946: E/AndroidRuntime(283): at dalvik.system.NativeStart.main(Native Method) 
08-06 17:44:09.946: E/AndroidRuntime(283): Caused by: java.lang.reflect.InvocationTargetException 
08-06 17:44:09.946: E/AndroidRuntime(283): at com.victor.profile.MainActivity.RegisterActivity(MainActivity.java:36) 
08-06 17:44:09.946: E/AndroidRuntime(283): at java.lang.reflect.Method.invokeNative(Native Method) 
08-06 17:44:09.946: E/AndroidRuntime(283): at java.lang.reflect.Method.invoke(Method.java:521) 
08-06 17:44:09.946: E/AndroidRuntime(283): at android.view.View$1.onClick(View.java:2067) 
08-06 17:44:09.946: E/AndroidRuntime(283): ... 11 more 
08-06 17:44:09.946: E/AndroidRuntime(283): Caused by: java.lang.IllegalStateException: System services not available to Activities before onCreate() 
08-06 17:44:09.946: E/AndroidRuntime(283): at android.app.Activity.getSystemService(Activity.java:3526) 
08-06 17:44:09.946: E/AndroidRuntime(283): at com.android.internal.app.AlertController$AlertParams.<init>(AlertController.java:743) 
08-06 17:44:09.946: E/AndroidRuntime(283): at android.app.AlertDialog$Builder.<init>(AlertDialog.java:273) 
08-06 17:44:09.946: E/AndroidRuntime(283): at com.victor.profile.MainActivity.dbFail(MainActivity.java:43) 
08-06 17:44:09.946: E/AndroidRuntime(283): at com.victor.profile.ConnectDB.checkDataBase(ConnectDB.java:83) 
08-06 17:44:09.946: E/AndroidRuntime(283): at com.victor.profile.ConnectDB.createDataBase(ConnectDB.java:47) 
08-06 17:44:09.946: E/AndroidRuntime(283): ... 15 more 
08-06 17:44:09.965: W/ActivityManager(58): Force finishing activity com.victor.profile/.MainActivity 
08-06 17:44:10.315: I/ARMAssembler(58): generated scanline__00000077:03515104_00000000_00000000 [ 33 ipp] (47 ins) at [0x342d00:0x342dbc] in 385721 ns 
08-06 17:44:10.525: W/ActivityManager(58): Activity pause timeout for HistoryRecord{44fee218 com.victor.profile/.MainActivity} 
08-06 17:44:20.796: W/ActivityManager(58): Activity destroy timeout for HistoryRecord{44fee218 com.victor.profile/.MainActivity}* 
+0

Необходимо отправить сообщение об ошибке logcat. Если есть принудительное закрытие, вы должны увидеть красным фатальное исключение. Опубликуйте первые пять строк кода после фатального. –

+0

Если вы не видите logcat goto windows-> showview-> logcat –

ответ

2

Вы не можете определить путь к вашему ха й диск в эмуляторе, как это:

private static String DB_PATH = "C:/Users/Victor/Dropbox/workspace/Profile/database"; 

Эмулятор создает среду, которая имитирует реальное устройство как можно больше. У него есть собственная файловая структура, и ваш подход неверен. Вместо того, чтобы использовать эту функцию, чтобы создать базу данных:

checkDB = SQLiteDatabase.openDatabase(DB_NAME, null, SQLiteDatabase.OPEN_READONLY); 

Если вы хотите получить доступ к базе данных в эмуляторе прочитать: Where does Android emulator store SQLite database?

Новый LogCat

При вызове new ConnectDB(this) класс SQLiteOpenHelper создает для вас. Вам не нужен ваш метод createDataBase().

И когда вы используете getReadableDatabase(), как это:

try { 
    SQLiteDatabase database = mDbHelper.getReadableDatabase(); 
} 
catch(SQLiteException exception) { 
    // Database didn't open, exit app gracefully 
} 

Тогда вам не нужен ваш метод checkDataBase() либо, оба процесса выполняются уже на SQLite.

Наконец вам не нужно выходить из приложения в onDestory(). Попытка закрыть закрывающееся приложение является излишним. Также, если вы хотите закрыть приложение, используйте метод Android finish(). Всегда используйте команды Android над стандартной Java-командой.

+0

Я попробую вашу ссылку, надеюсь, что она решит мою проблему, спасибо, чувак, через несколько минут. Я вернусь, чтобы ответить, спасибо –

+0

Я исправил, что вы сказали, но все еще не работали, приложение все еще crashs =/у вас нет идей больше о том, что должно быть? –

+0

Лучший способ узнать, что происходит, это прочитать LogCat. Откройте окно LogCat в Eclipse, выделите красные строки ошибок, нажмите Crtl + C, нажмите «изменить» в левом нижнем углу вашего вопроса, вставьте ошибки LogCat в свои вопросы, повторно выделите ошибки, это ваш вопрос и нажмите Crtl + K для форматирования ошибок LogCat для переполнения стека. (Это может показаться запутанным, но это просто.) – Sam

Смежные вопросы