0

如果我有一个 SQLiteOpenHelper 类,其中包含用于将对象插入数据库的方法,如果我从 AsyncTask 内部调用此方法,那么对数据库的调用是在单独的线程上还是在主 UI 线程中完成?

我认为数据库调用将在后台线程上进行。我是否错误地理解了 asynctask 类?我是否必须重写我的 SQLiteOpenHelper 中的所有数据库调用才能使用异步任务?

目前,我在我的安卓设备上遇到了很多延迟,并且有一条消息说:

The application may be doing too much work on its main thread.

我正在调用一个 web 服务,该服务响应一个 json 字符串,我在 doinbackground 方法中解析该字符串,然后将项目插入数据库。

public class DB_Async {
public void replaceDeck(String jsonString, Delegate d){
    ReplaceDeck del = new ReplaceDeck();
    del.setDelegate(d);
    del.addParameter("json", jsonString);
    del.execute();
}
private class ReplaceDeck extends AsyncTask<String, Object, String> {

    private Delegate delegate;
    private Exception error;
    private Hashtable<String, String> parameters = new Hashtable<String, String>();

    public void setDelegate(Delegate d){
        delegate = d;
    }

    public void addParameter(String key, String value){
        parameters.put(key, value);
    }

    @Override
    protected void onPreExecute() {                     //Main Thread
        super.onPreExecute();

        if(delegate != null)
            delegate.onStart();
    }

    @Override
    protected void onPostExecute(String result) {       //Main Thread
        super.onPostExecute(result);
        if(delegate != null)
            delegate.onResult(result, error);
    }

    protected String doInBackground(String... params){  //BACKGROUND THREAD
        String currDate = new Date().toString();
        SQLdataHelper mDataHelper = SQLdataHelper.getInstance();
        String result = null;
        String jsonString = parameters.get("json");
        try {
            JSONObject jsonObj    = new JSONObject(jsonString);    
            JSONArray  jsonDecks = jsonObj.getJSONArray("decks");   
            for(int i = 0; i < jsonDecks.length(); i++){
                Deck newDeck = new Deck();
                int new_deck_id =  mDataHelper.addDeck(newDeck); // call to SQLOpenHelper
            }           
        } catch (JSONException e) {
            e.printStackTrace();
        }catch(Exception e)
        {
            System.out.println(e);
            result = e.getMessage();
            error = e;
        }
        return result;
    }
}

我的数据库只是在我的 Decks 列中插入了一个新行:

 public synchronized long addDeck(Deck deck){
    String currDate = new Date().toString();
    ContentValues values = new ContentValues();
    values.put(DB_DECK_UID_COLUMN, deck.student_id);
    values.put(DB_DECK_NAME_COLUMN, deck.name);
    values.put(DB_DECK_DESC_COLUMN, deck.description);
    values.put(DB_DECK_DIFFICULTY_COLUMN, deck.difficulty);
    values.put(DB_DECK_COUNT_COLUMN, deck.cardCount);
    values.put(DB_DECK_RATING_COLUMN, deck.rating);
    values.put(DB_DECK_CREATED_COLUMN, currDate);
    values.put(DB_DECK_UPDATED_COLUMN, currDate);
    values.put(DB_DECK_WEBID_COLUMN, deck.web_id);
    values.put(DB_DECK_NEED_SYNC, 0);
    long deck_id = mDB.insert(DB_DECK_TABLE, null, values);
    return deck_id;
}

为了调用这个方法,我创建了一个新的委托并调用了我的 ReplaceDeck。

DB_Async.Delegate asyncDelegate = new DB_Async.Delegate() {
        @Override
        public void onStart() {
            // TODO Auto-generated method stub
        }
        @Override
        public void onResult(String result, Exception e) {
            Toast.makeText(mContext, "Successful Download", Toast.LENGTH_SHORT).show();
        }
    };
    try{
        DB_Async bf = new DB_Async(mContext);
        bf.replaceDeck(jsonString, asyncDelegate);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
4

1 回答 1

0

我正在调用一个 web 服务,该服务响应一个 json 字符串,我在 doinbackground 方法中解析该字符串,然后将项目插入数据库。

意味着您正在尝试在 UI Thread 上进行 webservice 调用,然后将其replaceDeck作为参数传递给AsyncTask在 doinbackground 中启动和解析它。

您还需要将 webservice 调用相关代码放在 AsyncTask 的 doinbackground 方法中。为此,您可以使用两个 AsyncTask 的一个来调用 web 服务以获取数据,第二个用于在 DB 中插入数据。

于 2013-01-23T18:31:06.477 回答