經過幾天絕望的日子,我終於創建了幾乎可行的例子。AsyncTask with ProgressDialog vs orientation orientation
onCreate中的目標:我想在AsyncTask中下載和解析XML文件,顯示進度對話框,更新UI並關閉對話框。
問題:當方向更改時重新啓動活動並且AsyncTask失去對它的引用。有很多關於它的問題和博客。但我無法找出爲什麼這個特定的解決方案不起作用。或者在這種情況下android如何處理對話。
該州:當我開始一個應用程序時,一切都很好。我可以旋轉設備,然後我可以通過菜單再次手動啓動任務。但任務完成後,我再次改變方向彈出對話框(按預期),沒有其他事情發生。沒有進展變化,沒有對話駁回。 AsyncTask正常結束。
代碼:
package com.test;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
public class Test extends TabActivity {
DownloadFileAsync task;
ProgressDialog progressDialog;
static final int PROGRESS_DIALOG = 0;
private static Data data;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/* - Run from different locations bug - */
//http://code.google.com/p/android/issues/detail?id=2373
if (!isTaskRoot()) {
final Intent intent = getIntent();
final String intentAction = intent.getAction();
if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) &&
intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) {
finish();
}
}
/* - /Run from different locations bug */
/* -------------- Tabs ---------------- */
Resources res = getResources();
TabHost mTabHost = getTabHost();
mTabHost.addTab(mTabHost.newTabSpec("overview").setIndicator("MYTAB1",res.getDrawable(R.drawable.ic_tab_home)).setContent(R.id.tab1));
mTabHost.setCurrentTab(0);
/* -------------- /Tabs --------------- */
/* -------------- /Data --------------- */
task = (DownloadFileAsync)getLastNonConfigurationInstance();
if(task!= null) {
task.setActivity(this);
} else {
if(data == null) {
File datafile = this.getFileStreamPath("data.dat");
if(datafile.exists()){
//Log.d("log", "File exists!");
try {
long time = System.currentTimeMillis();
ObjectInputStream obj = new ObjectInputStream(new FileInputStream(datafile));
data = (Data)obj.readObject();
obj.close();
Log.d("time", "loaded in:"+(System.currentTimeMillis()- time));
if(data.isUpToDate() || !isOnline()){
update();
}
} catch (Exception e) {
e.printStackTrace();
datafile.delete();
data = null;
}
//Log.d("log", "Passed?");
}
}
/* DEBUG if(data == null || !data.isUpToDate())*/ this.synchronize();
}
/* -------------- /Data --------------- */
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add("Synchronize").setIcon(R.drawable.ic_menu_refresh);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
synchronize();
return super.onOptionsItemSelected(item);
}
@Override
public Object onRetainNonConfigurationInstance() {
if(task != null) task.setActivity(null);
return(task);
}
protected Dialog onCreateDialog(int id) {
switch (id) {
case PROGRESS_DIALOG:
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Aktualizuji ...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(false);
//progressDialog.show();
return progressDialog;
default:
return null;
}
}
public void update() {
}
private void onTaskCompleted() {
task = null;
dismissDialog(PROGRESS_DIALOG);
Log.d("tok","Task.onComplete");
update();
}
public void synchronize(){
if(isOnline()) {
showDialog(PROGRESS_DIALOG);
progressDialog.setProgress(0); // <-- this is the last time progressDialog updates
task = new DownloadFileAsync(this);
task.execute();
}
}
public boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(WaspActivity.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}
private static class DownloadFileAsync extends AsyncTask<String, String, String> {
private Data tempData;
private Test activity;
private int progress = 0;
private File metafile;
private File tempDir;
private FileOutputStream fos;
public DownloadFileAsync(Test activity) {
this.setActivity(activity);
... some more init ...
}
public void setActivity(Test activity) {
this.activity = activity;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
tempData = new Data();
}
@Override
protected String doInBackground(String... aurl) {
try {
... some heavy load ...
//this.progress = someValue;
} catch (Exception e) {
Log.d("Error", "Error while processing files. Code:"+e.getMessage());
e.printStackTrace();
}
//Log.d("time","Task "+(System.currentTimeMillis() - time));
return null;
}
protected void onProgressUpdate(String... progress) {
if(activity != null) activity.progressDialog.setProgress(this.progress);
}
@Override
protected void onPostExecute(String unused) {
data = tempData;
tempData = null;
if(activity != null) {
activity.onTaskCompleted();
activity = null;
}
}
}
}
看[這裏](http://www.codeproject.com/Articles/162201/Painless-AsyncTask-and-ProgressDialog-Usage)。你可以在那裏找到你的問題的答案。這是一個非常優雅的解決方案。 – Yury 2012-07-05 08:28:59
查看我關於此主題的帖子:[**使用'Fragment's **處理配置更改](http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html) – 2013-04-30 16:47:24