嘿, 因此,環顧四周看來,共識是通過使用publishProgress()將更新用戶界面以進行更長時間的計算。我似乎不喜歡實現這個,但是,因爲當我運行這個代碼時,我得到了一個ANR。你能幫我理解爲什麼嗎?在AsyncTask中更新用戶界面
這裏是我的代碼: http://pastebin.com/zQNhkDJ9
嘿, 因此,環顧四周看來,共識是通過使用publishProgress()將更新用戶界面以進行更長時間的計算。我似乎不喜歡實現這個,但是,因爲當我運行這個代碼時,我得到了一個ANR。你能幫我理解爲什麼嗎?在AsyncTask中更新用戶界面
這裏是我的代碼: http://pastebin.com/zQNhkDJ9
你的問題可能是你的doInBackground功能只是打電話publishProgress。您的所有工作都在publishProgress中完成,它在UI線程上運行,所以您仍然可以通過這種方式獲得ANR。您需要在doInBackground中完成繁重的工作,然後一旦完成處理,您可以更新UI線程。
你需要讓你的AsyncTask成爲一個靜態的內部類,它有一個屬性,它是對你的Activity的引用。然後你可以直接調用Activity上的方法 - 就像UIupdate()一樣。
您必須注意的一個問題是,您現在必須非常小心地清除對onPause回調中的Activity的引用,否則您設置了循環引用,這會導致內存泄漏。
我的模式是有另一個基本的Java對象,通常是另一個私人靜態類,我稱之爲「StateHolder」,它是我的網關,用於處理AsyncTask的東西,比如初始化它並清除它(設置爲NULL )並在輪換更改期間取消正在進行的任何任務。在「onRetainNonConfigurationInstance」回調中,您可以使用StateHolder作爲編組對象。
下面是一些粗糙的代碼:
私有靜態類GetConnectionsStatusTask擴展的AsyncTask { 私人BoothActivity mActivity; 私人異常mReason;
public GetConnectionsStatusTask(BoothActivity activity) {
super();
mActivity = activity;
}
public void setActivity(BoothActivity activity) {
mActivity = activity;
}
@Override
protected void onPreExecute() {
if(mActivity != null) {
mActivity.startProgressBar("Loading", "Please wait");
}
}
@Override
protected Connections doInBackground(Void... values) {
try {
App app = (App)mActivity.getApplication();
return(app.getApp().userConnections());
}catch(Exception e) {
mReason = e;
return(null);
}
}
@Override
protected void onPostExecute(Connections status) {
super.onPostExecute(status);
if(mActivity != null) {
mActivity.completedConnectionsStatusCheck(status, mReason);
}
}
}
私有靜態類的StateHolder { 私人GetConnectionsStatusTask connectionsTask;
public void cancelTasks() {
if (connectionsTask != null) {
connectionsTask.setActivity(null);
connectionsTask.cancel(true);
connectionsTask = null;
}
}
public void setActivityForTasks(BoothActivity activity) {
if (connectionsTask != null) {
connectionsTask.setActivity(activity);
}
}
public void startConnections(BoothActivity activity) {
if(mIsConnectionsChecking == false) {
mIsConnectionsChecking = true;
connectionsTask = new GetConnectionsStatusTask(activity);
connectionsTask.execute();
}
}
}
中的onPause
然後,我有這樣的代碼:
if(mStateHolder != null) {
mStateHolder.cancelTasks();
}
而在的onCreate你可以重新虛增您的StateHolder像這樣:
Object retained = getLastNonConfigurationInstance();
if(retained != null && retained instanceof StateHolder) {
mStateHolder = (StateHolder) retained;
mStateHolder.setActivityForTasks(this);
} else {
mStateHolder = new StateHolder();
}
這也將重新初始化您的StateHolder與當前的活動,所以你可以重新建立任何UI小部件,如進度條更新等。
使用此模式,您實際上可以運行異步任務,並通過進度條重新初始化自己來處理輪換更改。
我沒有看到您的代碼中您創建和執行AsyncTask的任何位置。這是否發生在另一個文件? – BigFwoosh 2011-05-09 18:40:24
是的,我不認爲我需要發佈該 – Cody 2011-05-09 18:41:51