简体   繁体   English

SQLiteException - 仅在某些设备上发生

[英]SQLiteException - only happens on some devices

I recently published an app to the market place. 我最近向市场发布了一款应用程序。 From the developers console it seems about 1-2% of my users are having this issue. 从开发人员控制台看,似乎有1-2%的用户遇到此问题。 1-2% is small but people are more inclined to leave comments when something doesn't work rather than when it does which could negatively effect downloads. 1-2%很小,但是当某些东西不起作用时,人们更倾向于发表评论,而不是可能会对下载产生负面影响。

Unfortunately the developers console only lists the platform as 'other', but my app is available to those with SDK 1.6+. 不幸的是,开发人员控制台仅将平台列为“其他”,但我的应用程序可供SDK 1.6+的用户使用。 I'm also unable to recreate this issue and no user has contacted me directly so I'm unable to get any more information about the devices it fails on. 我也无法重新创建此问题,并且没有用户直接与我联系,因此我无法获得有关其失败的设备的更多信息。

Here is the stack 这是堆栈

android.database.sqlite.SQLiteException: no such table: QUESTIONS: , while compiling: SELECT * FROM QUESTIONS WHERE DIFFICULTY=2 ORDER BY RANDOM() LIMIT 20
at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:80)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:46)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:53)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1434)
at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1404)
at com.app.myapp.db.DBHelper.getQuestionSet(DBHelper.java:140)
at com.app.myapp.SplashActivity.getQuestionSetFromDb(SplashActivity.java:109)
at com.app.myapp.SplashActivity.onClick(SplashActivity.java:58)
at android.view.View.performClick(View.java:2421)
at android.view.View$PerformClick.run(View.java:8867)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:5068)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)

getQuestionSetFromDb(SplashActivity.java:109) refers to getQuestionSetFromDb(SplashActivity.java:109)指的是

List<Question> questions = myDbHelper.getQuestionSet(diff, numQuestions);

Which refers to 哪个指的是

public List<Question> getQuestionSet(int difficulty, int numQ){
    List<Question> questionSet = new ArrayList<Question>();
    Cursor c = myDataBase.rawQuery("SELECT * FROM QUESTIONS WHERE DIFFICULTY=" + difficulty +
            " ORDER BY RANDOM() LIMIT " + numQ, null);
    while (c.moveToNext()){
        //Log.d("QUESTION", "Question Found in DB: " + c.getString(1));
        Question q = new Question();
        q.setQuestion(c.getString(1));
        q.setAnswer(c.getString(2));
        q.setOption1(c.getString(3));
        q.setOption2(c.getString(4));
        q.setOption3(c.getString(5));
        q.setRating(difficulty);
        questionSet.add(q);
    }
    return questionSet;
}

} }

Does anyone know of a probable cause? 有谁知道可能的原因? It's strange this is only happening with a small amount of installs and being unable to determine the SDK level/device they are using makes it more difficult. 奇怪的是,这只是在少量安装的情况下发生,并且无法确定他们正在使用的SDK级别/设备使其变得更加困难。

Any help is appreciated 任何帮助表示赞赏

EDIT: Due to the responses I'm including how the db is created. 编辑:由于响应,我包括如何创建数据库。

First, my activity has this (this is the same method which causes the crash) 首先,我的活动有这个(这是导致崩溃的相同方法)

    private List<Question> getQuestionSetFromDb() throws Error {
    int diff = getDifficultySettings();
    int numQuestions = getNumQuestions();
    DBHelper myDbHelper = new DBHelper(this);
    try {
        myDbHelper.createDataBase();
    } catch (IOException ioe) {
        throw new Error("Unable to create database");
    }
    try {
        myDbHelper.openDataBase();
    }catch(SQLException sqle){
        throw sqle;
    }
    List<Question> questions = myDbHelper.getQuestionSet(diff, numQuestions);
    myDbHelper.close();
    return questions;
}

myDBhelper.createdatabase() calls myDBhelper.createdatabase()调用

public void createDataBase() throws IOException{

    boolean dbExist = checkDataBase();
    if(!dbExist)
    {
        //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");
        }
    }
}

checkDatabase() checkDatabase()

    private boolean checkDataBase(){
    SQLiteDatabase checkDB = null;
    try{
        String myPath = DB_PATH + DB_NAME;
        checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
    }catch(SQLiteException e){
        //database does't exist yet.
    }
    if(checkDB != null){
        checkDB.close();
    }

    return checkDB != null ? true : false;
}

copyDatabase() copyDatabase()

    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();

}

Variables 变量

    private static String DB_PATH = "/data/data/com.app.myapp/databases/";
private static String DB_NAME = "questionsDb";
private SQLiteDatabase myDataBase; 
private final Context myContext;

Apoligies, I really should have included this initially Apoligies,我真的应该包括这个

The error reports about a missing "QUESTIONS" database. 错误报告有关缺少“QUESTIONS”数据库的信息。 DB_NAME is "questionsDb". DB_NAME是“questionsDb”。

The int difficulty, appended with + to a string, puzzles me too (was already reported from another user earlier in this thread). int难度,附加+到一个字符串,也让我感到困惑(已经在此线程的早期报告过另一个用户)。

I just feel the way you are creating the database is causing the problem. 我只是觉得你创建数据库的方式导致了问题。 There is nothing wrong with it; 没有什么问题; as you said it works on 98% of the devices. 正如你所说,它适用于98%的设备。

In my opinion, you are probably better off extending SQLiteOpenHelper . 在我看来,你最好扩展SQLiteOpenHelper This takes care of creating your database if it doesn't exist and you don't have to do any checks manually that you do. 如果数据库不存在,则负责创建数据库并且您不必手动执行任何检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM