函数getDatabase()递归调用错误?

时间:2019-07-07 11:02:03

标签: sqlite android-asynctask sqliteopenhelper

我正在使用SQLiteDatabase在AsyncTask doInBackground()方法中存储在后台购买的数据,有时如果接收到的数据不在数据库中,我会插入数据,如果接收到的数据已经存在且未读,我会标记为数据为未读... 但是它说在doInBackground Method()中递归调用了getDatabase ... 是因为我在后台线程或其他某些线程上执行了操作而导致的问题吗? 该应用程序从网站上抓取新闻并将其显示在应用程序中,如果看到的新闻标记为旧新闻,还将添加到sqlite数据库中。

2019-07-07 16:16:46.664 27223-27276/com.github.chillmonk2.mycollege E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
    Process: com.github.chillmonk2.mycollege, PID: 27223
    java.lang.RuntimeException: An error occurred while executing doInBackground()
        at android.os.AsyncTask$3.done(AsyncTask.java:365)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
        at java.util.concurrent.FutureTask.run(FutureTask.java:271)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:257)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at java.lang.Thread.run(Thread.java:784)
     Caused by: java.lang.IllegalStateException: getDatabase called recursively
        at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:246)
        at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:206)
        at com.github.chillmonk2.mycollege.NewsDbHelper.insertUrl(NewsDbHelper.java:36)
        at com.github.chillmonk2.mycollege.NewsDbHelper.onCreate(NewsDbHelper.java:26)
        at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:310)
        at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:206)
        at com.github.chillmonk2.mycollege.NewsDbHelper.urlExists(NewsDbHelper.java:59)
        at com.github.chillmonk2.mycollege.NewsFragment$TaskLoader.doInBackground(NewsFragment.java:144)
        at com.github.chillmonk2.mycollege.NewsFragment$TaskLoader.doInBackground(NewsFragment.java:111)
        at android.os.AsyncTask$2.call(AsyncTask.java:345)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:257) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) 
        at java.lang.Thread.run(Thread.java:784) 

这里是Db助手类

package com.github.chillmonk2.mycollege;

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

public class NewsDbHelper extends SQLiteOpenHelper {
   public static final String DATABASE_NAME = "news.db";
   public static final String TABLE_NAME = "newsIndex";
   public String COL_0 = "URL";
   public String COL_1 = "STATUS";
   SQLiteDatabase db;
   //SQLiteDatabase db = this.getWritableDatabase();
   public NewsDbHelper(Context context) {
       super(context, DATABASE_NAME, null ,1);
   }

   @Override
   public void onCreate(SQLiteDatabase db) {
       String createTable = " CREATE TABLE " + TABLE_NAME + "(" +
                           COL_0 + " TEXT PRIMARY KEY ," +
                           COL_1 + " INT );";
       db.execSQL(createTable);
       insertUrl("EMPTY");

   }

   @Override
   public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

   }
   public int insertUrl(String url)
   {
       db = this.getWritableDatabase();
       ContentValues values = new ContentValues();
       values.put(COL_0,url);
       values.put(COL_1,"0");//0 - Unread
       int result = (int)db.insert(TABLE_NAME,null,values);
       return result;
   }
   public int updateUrl(String Url)
   {
       db = this.getWritableDatabase();
       ContentValues values = new ContentValues();
       values.put(COL_0,Url);
       values.put(COL_1,1);
       int result = db.update(TABLE_NAME,values,COL_0 +"=?",new String[]{Url});
       return result;
   }
   public int deleteUrl(String Url)
   {

       int result = db.delete(TABLE_NAME,COL_0 + "=?",new String[]{Url});
       return result;
   }
   boolean urlExists(String Url){
      db = this.getWritableDatabase();
       String sql = "select * from "+TABLE_NAME + " where "+ COL_0 +"=?";
       Cursor cursor = db.rawQuery(sql,new String[]{Url});
       int count = cursor.getCount();
       if (count>=1)
           return true;
       else
           return false;
   }
   int getUrlStatus(String url)
   {
       //SQLiteDatabase db = this.getWritableDatabase();
       String sql = "select "+COL_1+" from "+TABLE_NAME + " where "+ COL_0 +"=?";
       Cursor cursor = db.rawQuery(sql,new String[]{url});
       int status = -1;
       while (cursor.moveToFirst())
       {
           status = cursor.getInt(cursor.getColumnIndex(COL_1));
       }
       return status;
   }


}

这是NewsFragment.java类中的代码部分

 @Override
        protected ArrayList<NewsObject> doInBackground(Void... voids) {
            String url = "http://rvrjc.ac.in/";
            ArrayList<NewsObject> mList = new ArrayList<NewsObject>();
            Document document;
            try {
                Log.d(MainActivity.class.getSimpleName(),"Main Activity");
                document = Jsoup.connect(url).get();
                Elements lnews = document.select("ul.newsticker li b");
                Elements bnews = document.select("div#galleryimage p");
                //Get the title of the website
                for (Element news : lnews) {//latest news Section
                    String s = "New";
                    String descNews = news.select("p").text();
                    String newsUrl = news.select("a").attr("href");
                    if (newsUrl.startsWith("http")) {
                        //do nothing
                        if(!db.urlExists(newsUrl)){
                            db.insertUrl(newsUrl);
                        }
                        else
                        {
                            int status = db.getUrlStatus(newsUrl);
                            if(status==1){//read
                                s = "Old";
                            }
                            else
                                s = "New";
                        }
                       mList.add(new NewsObject(descNews, newsUrl,s));
                    } else
                        mList.add(new NewsObject(descNews, url ,s));
                }
                for(Element news:bnews){

                    String descNews = news.select("p").text();
                    String newsGif = news.select("p img").attr("src");
                    String newsStatus = "Old" ;
                    if(newsGif.equals("new.gif"))
                    {

                        newsStatus = "New";
                        //System.out.println("News Status changed");
                    }
                    String newsUrl = news.select("a").attr("href");
                    if(newsUrl.startsWith("http"))
                    {
                        if(!db.urlExists(newsUrl)){
                            db.insertUrl(newsUrl);
                        }
                        else
                        {
                            int status = db.getUrlStatus(newsUrl);
                            if(status==1){//read
                                newsStatus = "Old";
                            }
                            else
                                newsStatus = "New";
                        }
                        //do nothing
                        mList.add(new NewsObject(descNews,newsUrl,newsStatus));
                    }
                    else
                        mList.add(new NewsObject(descNews,url,newsStatus));
                }



            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            Log.e("TAG",""+mList);
            return mList;
        }
        @Override
        protected void onPostExecute(ArrayList<NewsObject> newsArrayList) {
            super.onPostExecute(newsArrayList);
            progressDialog.dismiss();
            Log.e("TAG","Inside onPostExecute"+newsArrayList);
            mNewsAdapter.addAll(newsArrayList);
            mNewsAdapter.notifyDataSetChanged();
        }
    }

1 个答案:

答案 0 :(得分:1)

 insertUrl("EMPTY");

这是您尝试使用 NewsDbHelper 实例打开数据库的原因,而它仍然是打开数据库的一部分。

  • 构造实例时,不会打开数据库。直到您尝试访问打开的数据库后,它才会出现。正是在此打开过程中,调用onCreate方法(如果以前不存在该数据库)来创建数据库,因此您无法尝试使用this.getWritabaleDatabase,因为它仍在处理另一个{{ 1}}(或getReadableDatabase而不是getWritableDatabase

您可以使用

this.getWritableDatabase
  • 注意:该代码是内部代码,尚未运行或测试,因此可能包含一些错误。