Tôi đã làm việc trong một tuần để tìm giải pháp cho vấn đề nan giải này mà không cần phải chỉnh sửa tệp kê khai. Các giả định cho giải pháp này là:
- Bạn luôn cần sử dụng hộp thoại tiến trình
- Mỗi lần chỉ có một nhiệm vụ được thực hiện
- Bạn cần duy trì tác vụ khi điện thoại được xoay và hộp thoại tiến trình sẽ tự động bị loại bỏ.
Thực hiện
Bạn sẽ cần sao chép hai tệp được tìm thấy ở dưới cùng của bài đăng này vào không gian làm việc của bạn. Chỉ cần chắc chắn rằng:
Tất cả của bạn Activity
nên mở rộngBaseActivity
Trong onCreate()
, super.onCreate()
nên được gọi sau khi bạn khởi tạo bất kỳ thành viên nào cần được truy cập bởi ASyncTask
s của bạn . Ngoài ra, ghi đè getContentViewId()
để cung cấp id bố cục biểu mẫu.
Ghi đè onCreateDialog()
như bình thường để tạo các hộp thoại được quản lý bởi hoạt động.
Xem mã bên dưới để biết một lớp bên trong tĩnh mẫu để tạo AsyncT task của bạn. Bạn có thể lưu trữ kết quả của mình trong mResult để truy cập sau.
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
}
}
Và cuối cùng, để khởi động nhiệm vụ mới của bạn:
mCurrentTask = new MyTask(this);
((MyTask) mCurrentTask).execute();
Đó là nó!Tôi hy vọng giải pháp mạnh mẽ này sẽ giúp được ai đó.
BaseActivity.java (tự tổ chức nhập khẩu)
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;
}
}