Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 来自Sqlite数据库的Android Studio应用程序崩溃_Java_Database_Sqlite_Debugging_Android Studio - Fatal编程技术网

Java 来自Sqlite数据库的Android Studio应用程序崩溃

Java 来自Sqlite数据库的Android Studio应用程序崩溃,java,database,sqlite,debugging,android-studio,Java,Database,Sqlite,Debugging,Android Studio,我希望我的问题不要太宽泛。我真正想知道的是如何准确地告诉我的代码在哪里碰壁 我没有从我的调试器中得到错误,当仿真器启动使用sqlite数据库的活动时,应用程序只是崩溃(中的第三个活动)。我敢肯定,是将sqlite添加到我的代码中导致了崩溃,因为它在我添加它之前就已经运行了 这段代码只需要访问并读取我创建并粘贴到assets文件夹中的外部数据库。我在firefox的sqlite管理器中查看了sqlite数据库;这些信息似乎格式正确 我在app/src/Main中创建了一个资产文件夹,以便于添加外部

我希望我的问题不要太宽泛。我真正想知道的是如何准确地告诉我的代码在哪里碰壁

我没有从我的调试器中得到错误,当仿真器启动使用sqlite数据库的活动时,应用程序只是崩溃(中的第三个活动)。我敢肯定,是将sqlite添加到我的代码中导致了崩溃,因为它在我添加它之前就已经运行了

这段代码只需要访问并读取我创建并粘贴到assets文件夹中的外部数据库。我在firefox的sqlite管理器中查看了sqlite数据库;这些信息似乎格式正确

我在app/src/Main中创建了一个资产文件夹,以便于添加外部数据库“ex3.db”。然后我复制并粘贴了数据库文件

这是代码。LetterImage是一个包含从sqlite数据库检索到的字符串的类。MyDBHandler创建一个空数据库,将旧数据库复制到其中,并使用基于字符串的查询返回的值填充LetterImage。LoadSubjectActivity调用它们来搜索数据库并返回字符串

字母图像:

public class LetterImage {
private Integer _ID;
private String _letter;
private String _bigfilename;
private String _littlefilename;

//Constructor(s)
public LetterImage(){

}

public LetterImage(Integer ID, String letter, String bigfilename, String littlefilename){
    this._ID = ID;
    this._letter = letter;
    this._bigfilename = bigfilename;
    this._littlefilename = littlefilename;
}

public LetterImage(String letter){
    this._letter = letter;
}

//End Constructors

//Begin setters and getters

//ID is primary key
public void setID(Integer ID){
    this._ID = ID;
}

public Integer getID(){
    return this._ID;
}

//letter is main identifier used to search database
// passed to LoadSubjectActivity
// from ChooseSubjectABCActivity as extra from intent
public void setLetter(String letter){
    this._letter = letter;
}

public String getLetter(){
    return this._letter;
}

//Capital letter image file name
public void setBigFileName(String bigfilename){
    this._bigfilename = bigfilename;
}
public String getBigFileName(){
    return this._bigfilename;
}

//Lowercase Letter image file name
public void setLittleFileName(String littlefilename){
    this._littlefilename = littlefilename;
}
public String getLittleFileName(){
    return this._littlefilename;
}
}
现在,这里是MyDBHandler:

import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.content.Context;
import android.database.Cursor;

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

public class MyDBHandler extends SQLiteOpenHelper{

private final Context myContext;
private static Context context;

private static final int DATABASE_VERSION = 1;
private static String DB_PATH = "data/data" + context.getPackageName() + "/databases/";
private static final String DATABASE_NAME = "ex3.db";
public static final String TABLE_IMAGES = "tbl1";

private SQLiteDatabase myDataBase;

//Fields in Database
public static final String COLUMN_ID = "_id";
public static final String COLUMN_BIGIMAGEFILE = "bigImage";
public static final String COLUMN_LITTLEIMAGEFILE = "littleImage";
public static final String COLUMN_LETTER = "letter";

//Constructor
public MyDBHandler(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    this.myContext = context;
}

//if there is no existing database, create an empty one
public void createDatabase() throws IOException{
    boolean dbExist = checkDataBase();

    if(dbExist) {
        //do nothing
    }else {
        //call this method and create an empty database
        this.getReadableDatabase();

        try {
            copyDataBase();

        } catch(IOException e){
            throw new Error("Error copying database");

        }

    }
}

//check to see if there is an existing database
private boolean checkDataBase(){
    SQLiteDatabase checkDB = null;

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

    } catch (SQLiteException e){
        throw new Error("Unable to open database");
    }

    if(checkDB != null){

        checkDB.close();
    }

    return checkDB != null ? true : false;
}

//fills new empty database with existing database ex3
private void copyDataBase() throws IOException{

    InputStream myInput = myContext.getAssets().open(DATABASE_NAME);

    String outFileName = DB_PATH + DATABASE_NAME;

    OutputStream myOutput = new FileOutputStream(outFileName);

    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer))>0){
        myOutput.write(buffer, 0, length);
    }

    myOutput.flush();
    myOutput.close();
    myInput.close();
}

//opens the new database
public void openDatabase() throws SQLException {

    String myPath = DB_PATH + DATABASE_NAME;
    myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}

@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){

}


//creates an instance of letter LetterImage
//queries the new database by searching for the row with where the value of COLUMN_LETTER = letter
//fills LetterImage with the values from that row
public LetterImage findLetter(String letter) {
    String query = "Select * FROM " + TABLE_IMAGES + " WHERE " + COLUMN_LETTER + " =  \"" + letter + "\"";

    SQLiteDatabase db = this.getWritableDatabase();

    Cursor cursor = db.rawQuery(query, null);

    LetterImage LetterImage = new LetterImage();

    if (cursor.moveToFirst()) {
        cursor.moveToFirst();
        LetterImage.setID(Integer.parseInt(cursor.getString(0)));
        LetterImage.setBigFileName(cursor.getString(1));
        LetterImage.setLittleFileName(cursor.getString(2));
        LetterImage.setLetter(cursor.getString(3));
        cursor.close();
    } else {
        LetterImage = null;
    }
    db.close();
    return LetterImage;
}
}
最后,以下是LoadSubjectActivity类的相关部分:

public class LoadSubjectActivity extends MainActivity{

private DrawingView drawView;
private ImageButton currPaint;

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

    //receives string letter, from last activity
    //letter will be used to search array and return files names of the images to be used

    Intent intent = getIntent();
    String letter = intent.getExtras().getString("letter");

    //displayFN calls testDB(letter) to test the database
    //It should simply display the string returned by testDB()

    TextView displayFN = (TextView)findViewById(R.id.display_filenames);
    displayFN.setText(testDB(letter.toLowerCase()));


    //Eventually, button images will be filled dynamically

    ImageButton bigLetter = (ImageButton)findViewById(R.id.big_letter);
    ImageButton littleLetter = (ImageButton)findViewById(R.id.little_letter);
    bigLetter.setImageResource(R.drawable.biga);
    littleLetter.setImageResource(R.drawable.littlea);

    drawView = (DrawingView)findViewById(R.id.drawing);
    LinearLayout paintLayout = (LinearLayout)findViewById(R.id.paint_colors);
    currPaint = (ImageButton)paintLayout.getChildAt(0);
    currPaint.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.paint_pressed));
}

//Function to test the database takes a string as an argument to search the database
public String testDB(String letter){

    //create a new instance of dbHandler
    MyDBHandler dbHandler = new MyDBHandler(this);

    //try to either create an empty database or open the existing one
    try{
        dbHandler.createDatabase();
    } catch (IOException ioe){
        throw new Error("Unable to create database");
    }
    try{
        dbHandler.openDatabase();
    } catch(SQLException sqle){
        sqle.printStackTrace();
        throw new Error ("unable to open database");
    }


    LetterImage letterImage = dbHandler.findLetter(letter);
    String blFileName = letterImage.getBigFileName();

    //return the big letter image file name;
    return blFileName;

}

无论如何,我为任何明显的问题提前道歉。我已经尽我最大的能力追踪了逻辑…我正在自学java和sql…这是我的第一个android项目。非常感谢您的所有见解。

我想出了一种解决方法:

1.)重写checkDatabase()。我引用了本教程:,并发现:

private boolean checkDataBase(){

    File dbFile = new File(DB_PATH + DATABASE_NAME);
    //Log.v("dbFile", dbFile + "   "+ dbFile.exists());
    return dbFile.exists();
}
2.)硬代码DB_路径名,因为context.getFilesDir和getDatabasePath()没有返回我需要的路径


***通过logcat并将错误追溯到问题开始的确切位置,我是如何找到需要更改的内容的。在本例中,checkDatabase()没有向createDatabase()返回false,因此代码试图打开一个不存在的数据库。

如果您有答案,请编写一个答案。