getWritableDatabase的致命异常

时间:2012-03-21 22:52:44

标签: android sqlite

我有一个数据库管理器类,这会导致致命的异常。我不知道为什么,并希望有人能告诉我我做错了什么或我如何解决它..

代码:

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;

import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.util.Log;


public class DataBaseManager extends SQLiteOpenHelper{

    Context mContext;
    private static final String TAG = "DataBaseManager";
    private static final int dbVersion = 1;// ++ for DB  changes

    static final String dbName ="LCInstore";
    //Table Names
    static final String allIcons = "Icons";
    static final String allScreens = "Screens";
    static final String isLookUp = "LookUp";

    //Column Names - LookUp
    static final String colIconID = "IconID";
    static final String colScreenID = "ScreenID";
    static final String colRank = "Rank"; // order

    //Column Names shared by tables: Screens and Icons
    static final String colID = "ID";
    static final String colType = "Type";
    static final String colName = "Name";

    //Column Names - Icons
    static final String colImage = "Image";
    static final String colLabel = "Label";
    static final String colIntent = "Intent";
    static final String colIParams = "Params";


    public DataBaseManager(Context context) {
        super(context, dbName, null, dbVersion); 
        mContext = context;
        Log.v(TAG, "Initaited");

        // TODO Auto-generated constructor stub
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        Log.v(TAG, "on create called");

        // Create Icon Table if does not exist
         db.execSQL("CREATE TABLE "+ allIcons +"" +
                "("+colID + " INTEGER PRIMARY KEY AUTOINCREMENT, "+
                    colName + " TEXT," +
                    colImage + " BLOB," +
                    colLabel + " TEXT," +
                    colIntent + " TEXT," +
                    colType + " TEXT)");

        // Create Screens Table if does not exist
         db.execSQL("CREATE TABLE IF NOT EXISTS " + allScreens +"" +
                 "("+colID + " INTEGER PRIMARY KEY AUTOINCREMENT, "+
                    colName + " TEXT," +
                    colType + " TEXT)");

        //Create LookUp Table if does not exist
         db.execSQL("CREATE TABLE IF NOT EXISTS " + isLookUp +"" +
                 "("+colIconID + " INTEGER, "+
                    colScreenID + " INTEGER," +
                    colRank + " INTEGER)");

         InsertInitData(db);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
        Log.v(TAG, "on upgrade called");
        db.execSQL("DROP TABLE IF EXISTS "+allIcons);




    }
    /*private void InsertInitScreens(SQLiteDatabase db) {
        ContentValues cv=new ContentValues();
           cv.put(colName, "DR_Home");
           cv.put(colType, "dr_home");
           db.insert(allScreens, colID, cv);

           cv.put(colName, "DR_Sub");
           cv.put(colType, "dr_sub");
           db.insert(allScreens, colID, cv);
    }*/


    private void InsertInitData(SQLiteDatabase db) {
        //all Icons

        addIconFromWeb(this, "Icon1", "http://sapientboston.com/internal/elidd/red.png", "MY RED ICON", "someIntent", "generic");
        addIconFromWeb(this, "Icon2", "http://sapientboston.com/internal/elidd/red.png", "MY RED ICON", "someIntent", "generic");
        addIconFromWeb(this, "Icon3", "http://sapientboston.com/internal/elidd/red.png", "MY RED ICON", "someIntent", "generic");
        addIconFromWeb(this, "Icon4", "http://sapientboston.com/internal/elidd/red.png", "MY RED ICON", "someIntent", "generic");
        addIconFromWeb(this, "Icon5", "http://sapientboston.com/internal/elidd/red.png", "MY RED ICON", "someIntent", "generic");
        addIconFromWeb(this, "Icon6", "http://sapientboston.com/internal/elidd/red.png", "MY RED ICON", "someIntent", "generic");
        addIconFromRes(this, "Icon7", R.drawable.dr_tablet_icon, "MY RED ICON", "someIntent", "generic");
        addIconFromWeb(this, "Icon8", "http://sapientboston.com/internal/elidd/red.png", "MY RED ICON", "someIntent", "generic");
        addIconFromWeb(this, "Icon9", "http://sapientboston.com/internal/elidd/red.png", "MY RED ICON", "someIntent", "generic");
        addIconFromWeb(this, "Icon10", "http://sapientboston.com/internal/elidd/red.png", "MY RED ICON", "someIntent", "generic");
        addIconFromWeb(this, "Icon11", "http://sapientboston.com/internal/elidd/red.png", "MY RED ICON", "someIntent", "generic");
        addIconFromWeb(this, "Icon12", "http://sapientboston.com/internal/elidd/red.png", "MY RED ICON", "someIntent", "generic");


        ContentValues cv2=new ContentValues();
        cv2.put(colName, "DR_Home");
        cv2.put(colType, "dr_home");
        db.insert(allScreens, colID, cv2);

        cv2.put(colName, "DR_Sub");
        cv2.put(colType, "dr_sub");
        db.insert(allScreens, colID, cv2);

        addIconToScreen(1, "DR_Sub");
        addIconToScreen(2, "DR_Sub");
        addIconToScreen(3, "DR_Sub");
        addIconToScreen(4, "DR_Sub");
        addIconToScreen(5, "DR_Sub");
        addIconToScreen(6, "DR_Sub");
        addIconToScreen(7, "DR_Sub");
        addIconToScreen(8, "DR_Sub");
        addIconToScreen(9, "DR_Sub");
        addIconToScreen(10,"DR_Sub");

    }
    public byte[] getBlobFromRes(int d) {
        byte[] blobData;
        Bitmap bitmap = BitmapFactory.decodeResource(this.mContext.getResources(),
                d);

        ByteArrayOutputStream stream = new ByteArrayOutputStream();

        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        blobData = stream.toByteArray();
        return blobData;
    }

    public void addIconFromRes(DataBaseManager db,String name, int res, String label, String intent, String type ) {
        SQLiteDatabase mdb = db.getWritableDatabase();
        ContentValues cv=new ContentValues();
           cv.put(colName, "Icon7");
           cv.put(colImage, getBlobFromRes(res));
           cv.put(colLabel, "MY RED ICON 2");
           cv.put(colIntent, "someIntent");
           cv.put(colType, "generic");
           mdb.insert(allIcons, colID, cv);
    }



    public void addIconFromWeb (DataBaseManager db,String name, String url, String label, String intent, String type ) {
        new DownLoadImageTask (db, name, url, label, intent, type).execute(url);
    }

    private class DownLoadImageTask extends AsyncTask <String, Void, byte[]> {
        String pName;
        String pLabel;
        String pIntent;
        String pType;
        SQLiteDatabase mdb;

        public DownLoadImageTask(DataBaseManager db, String name, String url, String label, String intent, String type ){
            pName = name;
            pLabel = label;
            pIntent = intent;
            pType = type;
            mdb = db.getWritableDatabase();
        }
        @Override
        protected byte[] doInBackground(String... url) {
            byte[] blobData = null;
            DefaultHttpClient mHttpClient = new DefaultHttpClient();  
            HttpGet mHttpGet = new HttpGet(url[0]);  
            HttpResponse mHttpResponse;
            try {
                mHttpResponse = mHttpClient.execute(mHttpGet);
                if (mHttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {  

                HttpEntity entity = mHttpResponse.getEntity();
                if ( entity != null) {  

                 //ContentValues values = new ContentValues();  
                blobData = EntityUtils.toByteArray(entity);  
                 //mContext.getContentResolver().insert(MyBaseColumn.MyTable.CONTENT_URI, values);  
                } 
            } 
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return blobData;
        }
        @Override
        protected void onPostExecute(byte[] result) {

            ContentValues cv=new ContentValues();
               cv.put(colName, pName);
               cv.put(colImage, result);
               cv.put(colLabel, pLabel);
               cv.put(colIntent, pIntent);
               cv.put(colType, pType);
               mdb.insert(allIcons, colID, cv);
         }

    }





    public void addIconToScreen(int id, String screenName){

       SQLiteDatabase db=this.getWritableDatabase();
       int hsID = getScreenID(screenName);
       int hsTotal = getScreenTotal(hsID)+1;

       Cursor c = db.rawQuery("select * from "+ isLookUp +" where " + colIconID +  "="  +id + " and " + colScreenID +"=" +hsID, null);
       int numFound = c.getCount();

       if(numFound<1){
           ContentValues cv= new ContentValues();
           cv.put(colScreenID, hsID);
           cv.put(colIconID, id);
           cv.put(colRank, hsTotal);
           db.insert(isLookUp, colID, cv);
       }

       // else do nothing

    }

    public int getScreenID(String name){
        SQLiteDatabase db=this.getWritableDatabase();
        int sID;
        String selectQuery = "SELECT "+colID+ " FROM " + allScreens + " WHERE " +colName + "=" +name;
        Cursor cursor = db.rawQuery(selectQuery, null);
        sID = cursor.getInt(0);
        return sID;
    }


    public int getScreenTotal (int sID){

        SQLiteDatabase db=this.getReadableDatabase();
        int rows = (int) db.compileStatement("SELECT COUNT(*) FROM " + isLookUp + " where " + colScreenID + "="+sID).simpleQueryForLong();
        return rows;

    }

    public void DeleteScreenIcon (int screenID, int iconID){
        SQLiteDatabase db=this.getWritableDatabase();
        db.delete(isLookUp, colScreenID + "=" + screenID + " and " +colIconID+ "="+iconID, null);
        db.close();
    }




    // GETTERS

    public ArrayList<Integer> getScreenIcons(String screenName) {

        int sID = getScreenID(screenName);

        ArrayList<Integer> iconList = new ArrayList<Integer>();

        // Select All Query
        String selectQuery = "SELECT  * FROM " + isLookUp + " where " + colScreenID + "=" +sID + " order by " + colRank;

        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        // looping through all rows and adding to list
        if (cursor.moveToFirst()) {
            do {

                iconList.add(Integer.parseInt(cursor.getString(0)));


            } while (cursor.moveToNext());
        }
        Log.v(TAG, "List Created"); 
        cursor.close();
        db.close();
        // return contact list
        return iconList;



    }

    public String getIconLabel(int id){
        String label;
        String selectQuery = "SELECT "+colLabel+ " FROM " + allIcons + " WHERE " +colIconID + "="+id; 

        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        if(cursor != null)
        {
            cursor.moveToFirst();
            label = cursor.getString(0);
        }
        else{
            label ="";
        }
         cursor.close();
           db.close();
        return label;

    }

    public String getIconImage(int id){
        String image;
        String selectQuery = "SELECT "+colImage+ " FROM " + allIcons + " WHERE " +colIconID + "="+id; 

        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        if(cursor != null)
        {
            cursor.moveToFirst();
            image = cursor.getString(0);
        }
        else{
            image ="";
        }
         cursor.close();
         db.close();
         return image;

    }

    public int checkHomeScreen(Integer iD) {
        // TODO Auto-generated method stub
        int sID = getScreenID("DR_Home");
        SQLiteDatabase db=this.getReadableDatabase();
        int rows = (int) db.compileStatement("SELECT COUNT(*) FROM " + isLookUp + " where " + colScreenID + "="+ sID + " and "+ colIconID + "="+iD).simpleQueryForLong();
        return rows;
    }


}

错误: LOG ERROR

2 个答案:

答案 0 :(得分:0)

public void onCreate(SQLiteDatabase db) {
     InsertInitData(db);
}
private void InsertInitData(SQLiteDatabase db) {
    addIconFromWeb(this,..
}
public void addIconFromWeb (...
    new DownLoadImageTask (db..
}
public DownLoadImageTask(DataBaseManager db
    mdb = db.getWritableDatabase()
}
如果您的数据库不存在,

SQLiteOpenHelper.getWritableDatabase()会触发SQLiteOpenHelper.onCreate()。 (并不是因为你还在onCreate()

解决方案:使用提供的SQLiteDatabase db对象进行所有初始化(从网上下载在这里是一个非常糟糕的主意)你唯一不能做的就是在上下文中使用你的DataBaseManager db因为那将创建循环。创建数据库后,您可以安全地使用它。

下载数据并将其放入数据库应该从SQLiteOpenHelper的外部环境中完成。通过那个班级。

SQLiteOpenHelper的目的是帮助您打开一个包含您需要使用的表的数据库。就是这样。你不应该在这个课程中做真正繁重的工作,因为现在需要花费很长时间才能打开(.getWritableDatabase())你的数据库(或者如果你选择的话,你必须期望并解决这个限制)

答案 1 :(得分:0)

解决此问题的最简单方法是从此处更改DownLoadImageTask构造函数...

    public DownLoadImageTask(DataBaseManager db, <other parameters omitted>){
        ...
        mdb = db.getWritableDatabase();
    }

......对此...

    public DownLoadImageTask(SQLiteDatabase db, <other parameters omitted>){
        ...
        mdb = db;
    }

从此处更改addIconFromWeb(...)方法......

public void addIconFromWeb(DataBaseManager db, <other parameters omitted>) {
    new DownLoadImageTask (db, <other parameters omitted>).execute(url);
}

......对此...

public void addIconFromWeb(SQLiteDatabase db, <other parameters omitted>) {
    new DownLoadImageTask (db, <other parameters omitted>).execute(url);
}

InsertInitData(...)中的来电更改为...

private void InsertInitData(SQLiteDatabase db) {
    addIconFromWeb(db, <other parameters omitted>);
    ...
}