ฉันทำงานหนักเป็นเวลาหนึ่งสัปดาห์เพื่อหาทางออกให้กับภาวะที่กลืนไม่เข้าคายไม่ออกนี้โดยไม่ต้องหันไปแก้ไขไฟล์รายการ สมมติฐานสำหรับการแก้ปัญหานี้คือ:
- คุณจำเป็นต้องใช้กล่องโต้ตอบความคืบหน้าเสมอ
- ดำเนินการครั้งละหนึ่งงานเท่านั้น
- คุณต้องการให้งานคงอยู่เมื่อหมุนโทรศัพท์และไดอะล็อกความคืบหน้าจะถูกยกเลิกโดยอัตโนมัติ
การดำเนินงาน
คุณจะต้องคัดลอกสองไฟล์ที่ด้านล่างของโพสต์นี้ลงในพื้นที่ทำงานของคุณ ตรวจสอบให้แน่ใจว่า:
ทั้งหมดของคุณActivity
ควรขยายBaseActivity
ในonCreate()
, super.onCreate()
ควรจะเรียกว่าหลังจากที่คุณเริ่มต้นสมาชิกใด ๆ ที่จะต้องมีการเข้าถึงได้โดยคุณASyncTask
s นอกจากนี้แทนที่getContentViewId()
เพื่อให้รหัสรูปแบบ
แทนที่onCreateDialog()
เหมือนปกติเพื่อสร้างไดอะล็อกที่จัดการโดยกิจกรรม
ดูโค้ดด้านล่างสำหรับคลาสภายในตัวอย่างแบบคงที่เพื่อสร้าง AsyncTasks ของคุณ คุณสามารถเก็บผลลัพธ์ไว้ใน mResult เพื่อเข้าถึงในภายหลัง
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
}
}
และในที่สุดเมื่อต้องการเริ่มงานใหม่ของคุณ:
mCurrentTask = new MyTask(this);
((MyTask) mCurrentTask).execute();
แค่นั้นแหละ! ฉันหวังว่าโซลูชันที่มีประสิทธิภาพนี้จะช่วยให้ใครบางคน
BaseActivity.java (จัดการการนำเข้าด้วยตนเอง)
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;
}
}