如果我有一个 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();
}