1

Java 代码:公共类 SplashActivity 扩展 Activity 实现 OnClickListener {

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

    //////////////////////////////////////////////////////////////////////
    //////// GAME MENU  /////////////////////////////////////////////////
    Button playBtn = (Button) findViewById(R.id.playBtn);
    playBtn.setOnClickListener(this);
    Button settingsBtn = (Button) findViewById(R.id.settingsBtn);
    settingsBtn.setOnClickListener(this);
    Button rulesBtn = (Button) findViewById(R.id.rulesBtn);
    rulesBtn.setOnClickListener(this);
    Button exitBtn = (Button) findViewById(R.id.exitBtn);
    exitBtn.setOnClickListener(this);
}


/**
 * Listener for game menu
 */
@Override
public void onClick(View v) {
    Intent i;

    switch (v.getId()){
    case R.id.playBtn :
        //once logged in, load the main page
        //Log.d("LOGIN", "User has started the game");

        //Get Question set //
        List<Question> questions = getQuestionSetFromDb();

        //Initialise Game with retrieved question set ///
        GamePlay c = new GamePlay();
        c.setQuestions(questions);
        c.setNumRounds(getNumQuestions());
        ((ChuckApplication)getApplication()).setCurrentGame(c);  

        //Start Game Now.. //
        i = new Intent(this, QuestionActivity.class);
        startActivityForResult(i, Constants.PLAYBUTTON);
        break;

    case R.id.rulesBtn :
        i = new Intent(this, RulesActivity.class);
        startActivityForResult(i, Constants.RULESBUTTON);
        break;

    case R.id.settingsBtn :
        i = new Intent(this, SettingsActivity.class);
        startActivityForResult(i, Constants.SETTINGSBUTTON);
        break;

    case R.id.exitBtn :
        finish();
        break;
    }

}


/**
 * Method that retrieves a random set of questions from
 * the database for the given difficulty
 * @return
 * @throws Error
 */
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;
}


/**
 * Method to return the difficulty settings
 * @return
 */
private int getDifficultySettings() {
    SharedPreferences settings = getSharedPreferences(Constants.SETTINGS, 0);
    int diff = settings.getInt(Constants.DIFFICULTY, Constants.MEDIUM);
    return diff;
}

/**
 * Method to return the number of questions for the game
 * @return
 */
private int getNumQuestions() {
    SharedPreferences settings = getSharedPreferences(Constants.SETTINGS, 0);
    int numRounds = settings.getInt(Constants.NUM_ROUNDS, 20);
    return numRounds;
}

}

当我点击播放按钮时,应用程序停止。此按钮必须用于新活动才能打开连接到 sqlite 数据库的测验 qith 4 选项单选按钮。

Logcat 消息:

 `05-14 09:57:07.126: D/dalvikvm(19541): GC_CONCURRENT freed 189K, 12% free 2676K/3016K, paused 19ms+7ms, total 108ms
05-14 09:57:07.126: D/dalvikvm(19541): WAIT_FOR_CONCURRENT_GC blocked 47ms
05-14 09:57:07.486: I/Choreographer(19541): Skipped 55 frames!  The application may be doing too much work on its main thread.
05-14 09:57:07.516: D/gralloc_goldfish(19541): Emulator without GPU emulation detected.
05-14 09:57:10.116: D/AndroidRuntime(19541): Shutting down VM
05-14 09:57:10.116: W/dalvikvm(19541): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
05-14 09:57:10.146: E/AndroidRuntime(19541): FATAL EXCEPTION: main
05-14 09:57:10.146: E/AndroidRuntime(19541): java.lang.ClassCastException: android.app.Application cannot be cast to com.pixy.quiz.ChuckApplication
05-14 09:57:10.146: E/AndroidRuntime(19541):    at com.pixy.quiz.SplashActivity.onClick(SplashActivity.java:61)
05-14 09:57:10.146: E/AndroidRuntime(19541):    at android.view.View.performClick(View.java:4204)
05-14 09:57:10.146: E/AndroidRuntime(19541):    at android.view.View$PerformClick.run(View.java:17355)
05-14 09:57:10.146: E/AndroidRuntime(19541):    at android.os.Handler.handleCallback(Handler.java:725)
05-14 09:57:10.146: E/AndroidRuntime(19541):    at android.os.Handler.dispatchMessage(Handler.java:92)
05-14 09:57:10.146: E/AndroidRuntime(19541):    at android.os.Looper.loop(Looper.java:137)
05-14 09:57:10.146: E/AndroidRuntime(19541):    at android.app.ActivityThread.main(ActivityThread.java:5041)
05-14 09:57:10.146: E/AndroidRuntime(19541):    at java.lang.reflect.Method.invokeNative(Native Method)
05-14 09:57:10.146: E/AndroidRuntime(19541):    at java.lang.reflect.Method.invoke(Method.java:511)
05-14 09:57:10.146: E/AndroidRuntime(19541):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
05-14 09:57:10.146: E/AndroidRuntime(19541):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
05-14 09:57:10.146: E/AndroidRuntime(19541):    at dalvik.system.NativeStart.main(Native Method)
05-14 09:57:13.797: I/Process(19541): Sending signal. PID: 19541 SIG: 9

`

我的 BDHelper 类:

公共类 DBHelper 扩展 SQLiteOpenHelper{

//The Android's default system path of your application database.
private static String DB_PATH = "/data/data/com.pixy.quiz/databases/";
private static String DB_NAME = "questionsDb";
private SQLiteDatabase myDataBase; 
private final Context myContext;

/**
 * Constructor
 * Takes and keeps a reference of the passed context in order to access to the application assets and resources.
 * @param context
 */
public DBHelper(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)
    {
        //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){
        //database does't exist yet.
    }
    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_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) {
}

// 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.




public List<Question> getQuestionSet(int difficulty, int numQ){
    List<Question> questionSet = new ArrayList<Question>();
    Cursor c = myDataBase.rawQuery("SELECT * FROM question 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;
}

}

显现

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pixy.quiz"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="8" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.pixy.quiz.SplashActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".QuestionActivity" />
    <activity android:name=".RulesActivity" />
    <activity android:name=".EndgameActivity" />
    <activity android:name=".SettingsActivity" />
    <activity android:name=".AnswersActivity" />
</application>
<application 
android:allowBackup="true"
android:name="com.pixy.quiz.ChuckApplication"/>
</manifest>
4

2 回答 2

0

当你在做:

try {
        myDbHelper.createDataBase();
    } catch (IOException ioe) {
        throw new Error("Unable to create database");
    }
    try {
        myDbHelper.openDataBase();
    }catch(SQLException sqle){
        throw sqle;
    }

您实际上是在尝试打开两次数据库。您应该只在运行时打开它的一个实例。

于 2013-05-14T09:19:30.593 回答
0

您的 ChuckApplication 是否扩展了应用程序?

我认为您应该使用单例模式,如ChuckApplication.getInstance().setCurrentGame(c);

于 2013-09-26T09:19:01.767 回答