我正在尝试在我的应用程序中使用 DB SQLite,但遇到了麻烦。当我尝试运行应用程序时,Android 正在返回一个应用程序崩溃说“强制关闭”,我检查了代码以查看值和返回是否正常,并且似乎是,进行了一些调试,问题显然出在 createDataBase方法。他需要找到数据库的位置,我已经传入了一个变量 PATH,即使它仍然崩溃,不知道直接在平板电脑上运行是否是正确的原因我需要创建一个不同的路径,如数据/数据。 ...(发现正在研究,不确定)和 AVD(这就是问题所在)我需要指定数据库在我的桌面上的位置?
看一下代码:
连接数据库
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.
主要活动
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 错误
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}*