編輯:TL;博士你怎麼插入使用內容解析器和simpleCursorAdapter沒有listfragment掛分貝?更新SQLite數據庫,並使用SimpleCursorAdapter使UI掛起
我有我使用它來下載JSON數據的的AsyncTask。在該任務的onPostExecute()中,我調用handleNewMessageReponse()來更新我的Sqlite數據庫和結果。
private void handleNewMessagesResponse() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
//Step 1. Ensure we got something back.
if (mMessagesResponse.getMessages().length > 0){
//Step 2. Delete all Message DB rows.
getActivity().getContentResolver().delete(EntegraContentProvider.CONTENT_URI_MESSAGES, null, null);
//Step 3. Populate DB with new info.
//Hangs UI here.
for (int i = 0; i < mMessagesResponse.getMessages().length; i++) {
Messages messages = mMessagesResponse.getMessages()[i];
ContentValues values = new ContentValues();
values.put("id", messages.getId());
values.put("parent", messages.getParent());
values.put("type", messages.getType());
values.put("user", messages.getUser());
values.put("subject", messages.getSubject());
values.put("body", messages.getBody());
values.put("datetime", messages.getDatetime());
values.put("status", messages.getStatus());
values.put("touched", messages.getTouched());
//Perform the Insert.
getActivity().getContentResolver().insert(
EntegraContentProvider.CONTENT_URI_MESSAGES, values);
mWasDataLoaded = true;
}
}
mDataListener.onDataFetchComplete();
}
});
}
這是所有包含在其中實現LoaderManager.LoaderCallbacks
該片段的一個的onCreate爲ListFragment handleNewMessageResponse()的代碼看起來是這樣的:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] uiBindFrom = { "user", "subject" };
int[] uiBindTo = { R.id.messageUser , R.id.messageTitle };
getLoaderManager().initLoader(MESSAGES_LIST_LOADER, null, this);
adapter = new SimpleCursorAdapter(
getActivity(), R.layout.messages_list_item,
null, uiBindFrom, uiBindTo,
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
setListAdapter(adapter);
}
一切除了一個例外,下面的代碼部分需要10秒才能執行並在10秒內掛起UI /列表。
這部分是當UI掛起:
//Step 3. Populate DB with new info.
for (int i = 0; i < mMessagesResponse.getMessages().length; i++) {
Messages messages = mMessagesResponse.getMessages()[i];
ContentValues values = new ContentValues();
values.put("id", messages.getId());
values.put("parent", messages.getParent());
values.put("type", messages.getType());
values.put("user", messages.getUser());
values.put("subject", messages.getSubject());
values.put("body", messages.getBody());
values.put("datetime", messages.getDatetime());
values.put("status", messages.getStatus());
values.put("touched", messages.getTouched());
//Perform the Insert.
getActivity().getContentResolver().insert(
EntegraContentProvider.CONTENT_URI_MESSAGES, values);
可有人普萊舍點我在正確的方向,告訴我這個看似普通的任務的標準方法是什麼?這應該很簡單,但我很難找到適合我的用例的示例。
謝謝。
這是我的最終代碼。要流暢得多:
private class EventsFetcher extends AsyncTask<String, Void, EventsResponse> { private static final String TAG = "EventsFetcher";
@Override
protected EventsResponse doInBackground(String... params) {
EventsResponse returnResponse = null;
try {
//Create an HTTP client
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(mEventsBaseUrl);
//Perform the request and check the status code
HttpResponse response = client.execute(post);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
try {
//Read the server response and attempt to parse it as JSON
Reader reader = new InputStreamReader(content);
Gson gson = new Gson();
returnResponse= gson.fromJson(reader, EventsResponse.class);
content.close();
} catch (Exception ex) {
Log.e(TAG, "Failed to parse JSON due to: " + ex);
failedGettingEvents();
}
} else {
Log.e(TAG, "Server responded with status code: " + statusLine.getStatusCode());
failedGettingEvents();
}
} catch(Exception ex) {
Log.e(TAG, "Failed to send HTTP POST request due to: " + ex);
failedGettingEvents();
}
return returnResponse;
}
@Override
protected void onPostExecute(EventsResponse resultResponse) {
EventsResultsHandler resultsHandler = new EventsResultsHandler();
resultsHandler.execute(resultResponse);
}
}
private class EventsResultsHandler extends AsyncTask<EventsResponse, Void, String> {
private static final String TAG = "EventsResultsHandler";
@Override
protected String doInBackground(EventsResponse... params) {
try {
EventsResponse evResponse = params[0];
//Step 1. Ensure we got something back.
if (evResponse.getEvents().length > 0){
//Step 2. Populate Array with new info.
List<ContentValues> jsonResults = new ArrayList<ContentValues>();
for (int i = 0; i < evResponse.getEvents().length; i++) {
Events events = evResponse.getEvents()[i];
ContentValues values = new ContentValues();
values.put("start_date", events.getStart_date());
values.put("end_date", events.getEnd_date());
values.put("name", events.getName().replace("'","''"));
values.put("location", events.getLocation().replace("'","''"));
values.put("summary", events.getSummary().replace("'","''"));
values.put("lat", events.getLat());
values.put("lng", events.getLng());
values.put("is_active", events.getIs_active());
values.put("hide_calendar_button", events.getHide_calendar_button());
values.put("hide_map", events.getHide_map());
jsonResults.add(values);
}
//Step 3. Delete all data in table.
getActivity().getContentResolver().delete(EntegraContentProvider.CONTENT_URI_EVENTS, null, null);
//Step 4. Insert new data via via Bulk insert.
getActivity().getContentResolver().bulkInsert(EntegraContentProvider.CONTENT_URI_EVENTS, jsonResults.toArray(new ContentValues[jsonResults.size()]));
mWasDataLoaded = true;
}
} catch(Exception ex) {
Log.e(TAG, "Failed to update results due to: " + ex);
failedGettingEvents();
}
return null;
}
@Override
protected void onPostExecute(String result) {
mDataListener.onDataFetchComplete();
}
}
如果UI掛起你應該更新你的數據庫在後臺線程沒有UI一個 – pskink
pskink,這不正是我在上面的代碼我在做什麼? getActivity()。runOnUiThread(new Runnable(){ @Override public void run(){ – Doug
對runOnUiThread的調用會調度一個可在UI線程上執行的runnable(該方法確實按照名稱的名稱執行......)。關閉在後臺線程或與其他的AsyncTask的handleNewMessagesResponse代碼。 – NigelK