Database can't retrieve image or empty, cause

2020-05-01 04:14发布

问题:

My problem is java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0. I don't know to fix this error and i not found any problem on my array. I'm newbie in android. I hope you all understand. Maybe this is cause error on my error values.put(KEY_IMG, Utility.getBytes(quest.getBitmap()));. sorry my english.

UPDATE

database problem cause java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0

MainActivity.java

package com.example.quizjavatest;

import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import java.util.List;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;

public class MainActivity extends Activity  {

    List<Question> quesList;
    int score=0;
    int qid=0;
    ImageView quizimg; 
    Question currentQ;
    TextView txtQuestion;
    RadioButton rda, rdb, rdc;
    Button butNext;

@Override

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


            DbHelper db=new DbHelper(this);
            quesList=db.getAllQuestions();
            currentQ=quesList.get(qid);
            quizimg=(ImageView) findViewById(R.id.ImgQuiz); //img quiz
            txtQuestion=(TextView)findViewById(R.id.textView1); //question
            rda=(RadioButton)findViewById(R.id.radio0); //option A
            rdb=(RadioButton)findViewById(R.id.radio1); //option B
            rdc=(RadioButton)findViewById(R.id.radio2); //option C
            butNext=(Button)findViewById(R.id.button1); //button next
            setQuestionView();


            butNext.setOnClickListener(new View.OnClickListener() {     
                @Override
                public void onClick(View v) {
                    RadioGroup grp=(RadioGroup)findViewById(R.id.radioGroup1);
                    RadioButton answer=(RadioButton)findViewById(grp.getCheckedRadioButtonId());
                    Log.d("yourans", currentQ.getANSWER()+" "+answer.getText());
                    if(currentQ.getANSWER().equals(answer.getText()))
                    {
                        score++;
                        Log.d("score", "Your score"+score);
                    }
                    if(qid<5){                  
                        currentQ=quesList.get(qid);
                        setQuestionView();
                    }else{
                        Intent intent = new Intent(MainActivity.this, ResultActivity.class);
                        Bundle b = new Bundle();
                        b.putInt("score", score); //Your score
                        intent.putExtras(b); //Put your score to your next Intent
                        startActivity(intent);
                        finish();
                    }
                }
            });
        }

        private void setQuestionView()
        {
            quizimg.setImageBitmap(currentQ.getBitmap());
            txtQuestion.setText(currentQ.getQUESTION());
            rda.setText(currentQ.getOPTA());
            rdb.setText(currentQ.getOPTB());
            rdc.setText(currentQ.getOPTC());
            qid++  ;
        }
}

DbHelper.java

package com.example.quizjavatest;

import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.BitmapFactory;

public class DbHelper extends SQLiteOpenHelper{

    private Context mContext;
    private static final int DATABASE_VERSION = 1;
    // Database Name
    private static final String DATABASE_NAME = "PediaKids";
    // tasks table name

    private static final String TABLE_QUEST = "planet";

    // tasks Table Columns names
    private static final String KEY_ID = "id";
    private static final String KEY_IMG = "img";
    private static final String KEY_QUES = "question";
    private static final String KEY_ANSWER = "answer"; //correct option
    private static final String KEY_OPTA= "opta"; //option a
    private static final String KEY_OPTB= "optb"; //option b
    private static final String KEY_OPTC= "optc"; //option c
    private SQLiteDatabase dbase;
    public DbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        mContext = context;

    }
        @Override
        public void onCreate(SQLiteDatabase db) {

            dbase=db;
            String Sql = "CREATE TABLE IF NOT EXISTS " + TABLE_QUEST + " ( "
                    + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "+ KEY_IMG + "BLOB," + KEY_QUES
                    + " TEXT, "  + KEY_OPTA +" TEXT, " + KEY_OPTB +" TEXT, "+KEY_OPTC+" TEXT," + KEY_ANSWER + " TEXT)";



            db.execSQL(Sql);
            addQuestion();


            //db.close();
        }
        private void addQuestion()
        {
            Question q1=new Question(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher),"an operating system?", "SuSe", "BIOS", "DOS", "BIOS");
            this.addQuestion(q1);
            Question q2=new Question(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher),"Which of the following is NOT  "," SuSe", "BIOS", "DOS", "BIOS");
            this.addQuestion(q2);
            Question q3=new Question(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher),"Which of the following is the fastest","RAM", "FLASH","Register","Register");
            this.addQuestion(q3);
            Question q4=new Question(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher),"Which of the following device", "Router", "Bridge", "Hub","Router");
            this.addQuestion(q4);
            Question q5=new Question(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher),"Which of the following is NOT an" ,"Ruby","Python","BASIC","BASIC");
            this.addQuestion(q5);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldV, int newV) {
            // Drop older table if existed

            db.execSQL("DROP TABLE IF EXISTS " + TABLE_QUEST);

            // Create tables again
            onCreate(db);
        }

        // Adding new question

        public void addQuestion(Question quest) {
            //SQLiteDatabase db = this.getWritableDatabase();
            ContentValues values = new ContentValues();
            //values.put(KEY_ID, quest.getID());
            values.put(KEY_IMG, Utility.getBytes(quest.getBitmap()));
            values.put(KEY_QUES, quest.getQUESTION()); 
            values.put(KEY_ANSWER, quest.getANSWER());
            values.put(KEY_OPTA, quest.getOPTA());
            values.put(KEY_OPTB, quest.getOPTB());
            values.put(KEY_OPTC, quest.getOPTC());
            // Inserting Row
            dbase.insert(TABLE_QUEST, null, values);


        }


        public List<Question> getAllQuestions(){
            List<Question> quesList = new ArrayList<Question>();
            String selectQuery = "SELECT * FROM " + TABLE_QUEST + " ORDER BY RANDOM() LIMIT 5";
            dbase=this.getReadableDatabase();
            Cursor cursor = dbase.rawQuery(selectQuery, null);
            // looping through all rows and adding to list
            //==============================================
            if (cursor.moveToFirst()) {
                do {
                    Question quest = new Question();

                    quest.setID(cursor.getInt(0));
                    quest.setImage(Utility.getPhoto(cursor.getBlob(1)));
                    quest.setQUESTION(cursor.getString(2));
                    quest.setANSWER(cursor.getString(3));
                    quest.setOPTA(cursor.getString(4));
                    quest.setOPTB(cursor.getString(5));
                    quest.setOPTC(cursor.getString(6));
                    quesList.add(quest);
                } while (cursor.moveToNext());
            }
            // return quest list
            return quesList;
        }
        //==============================================

        public int rowcount()
        {
            int row=0;
            String selectQuery = "SELECT  * FROM " + TABLE_QUEST;
            SQLiteDatabase db = this.getWritableDatabase();
            Cursor cursor = db.rawQuery(selectQuery, null);
            row=cursor.getCount();
            return row;
        }
    }

Question.java

package com.example.quizjavatest;

import android.graphics.Bitmap;

public class Question {

        private int ID;
        private Bitmap bmp;
        //byte[] _image;
        private String QUESTION;
        private String OPTA;
        private String OPTB;
        private String OPTC;
        private String ANSWER;
        public Question()
        {
            /*ID=0;

            QUESTION="";
            OPTA="";
            OPTB="";
            OPTC="";
            ANSWER="";*/
        }
        public Question(Bitmap img, String qUESTION, String oPTA, String oPTB, String oPTC,
                String aNSWER ) {

            bmp = img;
            QUESTION = qUESTION;
            OPTA = oPTA;
            OPTB = oPTB;
            OPTC = oPTC;
            ANSWER = aNSWER;
        }
        public int getID()
        {
            return ID;

        }
        public Bitmap getBitmap(){
            return bmp;
        }
        public void setImage(Bitmap img){
            bmp = img;
        }
        /*public byte[] getImage(){
            return _image;
        }*/

        public String getQUESTION() {
            return QUESTION;
        }
        public String getOPTA() {
            return OPTA;
        }
        public String getOPTB() {
            return OPTB;
        }
        public String getOPTC() {
            return OPTC;
        }
        public String getANSWER() {
            return ANSWER;
        }
        public void setID(int id)
        {
            ID=id;
        }
        public void setQUESTION(String qUESTION) {
            QUESTION = qUESTION;
        }
        public void setOPTA(String oPTA) {
            OPTA = oPTA;
        }
        public void setOPTB(String oPTB) {
            OPTB = oPTB;
        }
        public void setOPTC(String oPTC) {
            OPTC = oPTC;
        }
        public void setANSWER(String aNSWER) {
            ANSWER = aNSWER;
        }

}

Utility.java

package com.example.quizjavatest;

import java.io.ByteArrayOutputStream;

import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;

public class Utility {
    // convert from bitmap to byte array
    public static byte[] getBytes(Bitmap bitmap) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(CompressFormat.PNG, 0, stream);
        return stream.toByteArray();
    }

    // convert from byte array to bitmap
    public static Bitmap getPhoto(byte[] image) {
        return BitmapFactory.decodeByteArray(image, 0, image.length);
    }
}

Logcat

    05-03 10:46:26.520: W/dalvikvm(9053): threadid=1: thread exiting with uncaught exception (group=0x41cff700)
05-03 10:46:26.585: E/AndroidRuntime(9053): FATAL EXCEPTION: main
05-03 10:46:26.585: E/AndroidRuntime(9053): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.quizjavatest/com.example.quizjavatest.MainActivity}: java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
05-03 10:46:26.585: E/AndroidRuntime(9053):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2295)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2349)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at android.app.ActivityThread.access$700(ActivityThread.java:159)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at android.os.Looper.loop(Looper.java:176)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at android.app.ActivityThread.main(ActivityThread.java:5419)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at java.lang.reflect.Method.invokeNative(Native Method)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at java.lang.reflect.Method.invoke(Method.java:525)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at dalvik.system.NativeStart.main(Native Method)
05-03 10:46:26.585: E/AndroidRuntime(9053): Caused by: java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
05-03 10:46:26.585: E/AndroidRuntime(9053):     at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at java.util.ArrayList.get(ArrayList.java:308)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at com.example.quizjavatest.MainActivity.onCreate(MainActivity.java:36)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at android.app.Activity.performCreate(Activity.java:5372)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
05-03 10:46:26.585: E/AndroidRuntime(9053):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2257)
05-03 10:46:26.585: E/AndroidRuntime(9053):     ... 11 more

回答1:

The problem is this two lines of code:

        quesList=db.getAllQuestions();
        currentQ=quesList.get(qid);

The first line actually just returns an empty array, and hence the second line throws unable to get item at position 0.

I think it is better to check the length of quesList before accessing it in this case:

if(quesList.size()>0){
  currentQ=quesList.get(qid);
}else{
  //maybe put some default question or show no question found message
}