Pracowałem przez tydzień, aby znaleźć rozwiązanie tego dylematu, bez uciekania się do edycji pliku manifestu. Założenia tego rozwiązania są następujące:
- Zawsze musisz użyć okna dialogowego postępu
- Jednocześnie wykonywane jest tylko jedno zadanie
- Musisz utrzymać zadanie, gdy telefon zostanie obrócony, a okno dialogowe postępu zostanie automatycznie odrzucone.
Realizacja
Musisz skopiować dwa pliki znajdujące się na dole tego postu do swojego obszaru roboczego. Upewnij się tylko, że:
Wszystkie twoje Activity
powinny się przedłużyćBaseActivity
W onCreate()
, super.onCreate()
powinien być nazywany po zainicjować żadnych elementów, które muszą być dostępne przez twoje ASyncTask
s. Zastąp także, getContentViewId()
aby podać identyfikator układu formularza.
Zastąp onCreateDialog()
jak zwykle, aby utworzyć okna dialogowe zarządzane przez działanie.
Zobacz kod poniżej przykładowej statycznej klasy wewnętrznej, aby Twoje AsyncTasks. Możesz zapisać swój wynik w mResult, aby uzyskać do niego dostęp później.
final static class MyTask extends SuperAsyncTask<Void, Void, Void> {
public OpenDatabaseTask(BaseActivity activity) {
super(activity, MY_DIALOG_ID); // change your dialog ID here...
// and your dialog will be managed automatically!
}
@Override
protected Void doInBackground(Void... params) {
// your task code
return null;
}
@Override
public boolean onAfterExecute() {
// your after execute code
}
}
I wreszcie, aby uruchomić nowe zadanie:
mCurrentTask = new MyTask(this);
((MyTask) mCurrentTask).execute();
Otóż to! Mam nadzieję, że to solidne rozwiązanie pomoże komuś.
BaseActivity.java (sam organizuj import)
protected abstract int getContentViewId();
public abstract class BaseActivity extends Activity {
protected SuperAsyncTask<?, ?, ?> mCurrentTask;
public HashMap<Integer, Boolean> mDialogMap = new HashMap<Integer, Boolean>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getContentViewId());
mCurrentTask = (SuperAsyncTask<?, ?, ?>) getLastNonConfigurationInstance();
if (mCurrentTask != null) {
mCurrentTask.attach(this);
if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null
&& mDialogMap.get((Integer) mCurrentTask.dialogId)) {
mCurrentTask.postExecution();
}
}
}
@Override
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
mDialogMap.put(id, true);
}
@Override
public Object onRetainNonConfigurationInstance() {
if (mCurrentTask != null) {
mCurrentTask.detach();
if (mDialogMap.get((Integer) mCurrentTask.dialogId) != null
&& mDialogMap.get((Integer) mCurrentTask.dialogId)) {
return mCurrentTask;
}
}
return super.onRetainNonConfigurationInstance();
}
public void cleanupTask() {
if (mCurrentTask != null) {
mCurrentTask = null;
System.gc();
}
}
}
SuperAsyncTask.java
public abstract class SuperAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
protected BaseActivity mActivity = null;
protected Result mResult;
public int dialogId = -1;
protected abstract void onAfterExecute();
public SuperAsyncTask(BaseActivity activity, int dialogId) {
super();
this.dialogId = dialogId;
attach(activity);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
mActivity.showDialog(dialogId); // go polymorphism!
}
protected void onPostExecute(Result result) {
super.onPostExecute(result);
mResult = result;
if (mActivity != null &&
mActivity.mDialogMap.get((Integer) dialogId) != null
&& mActivity.mDialogMap.get((Integer) dialogId)) {
postExecution();
}
};
public void attach(BaseActivity activity) {
this.mActivity = activity;
}
public void detach() {
this.mActivity = null;
}
public synchronized boolean postExecution() {
Boolean dialogExists = mActivity.mDialogMap.get((Integer) dialogId);
if (dialogExists != null || dialogExists) {
onAfterExecute();
cleanUp();
}
public boolean cleanUp() {
mActivity.removeDialog(dialogId);
mActivity.mDialogMap.remove((Integer) dialogId);
mActivity.cleanupTask();
detach();
return true;
}
}