需要一点帮助来理解这个 AsyncTask 场景
Need a little help understanding this AsyncTask scenario
我需要清楚地了解 AsyncTask 处理在我的场景中是如何发生的。我有一个普通的 java 对象,叫做 Donor。
有一个 activity(比如说 DonorDetailActivity)修改了这个供体对象。修改发生在 AsyncTask<>(例如 DonorEditService)中。因此,从 DonorDetailActivity 调用 DonorEditService 在后台线程中编辑 Donor,并将结果发布到主要 UI 线程。
DonorDetailActivity class
public class DonorDetailActivity extends ActionBarActivity implements AsyncTaskCallback<Donor>{
@Override
protected void onCreate(Bundle savedInstanceState) {
btnEditDonor.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) { //Invoke the DonorEditService
DonorEditService editService = new DonorEditService(DonorDetailActivity.this);
editService.execute(donor);
}
});
}
//Invoked from DonorEditService.onPostExecute(DonorBase updatedDonor)
@Override
public void onAsyncTaskCompleted(Donor updatedDonor) {
updateUI(); //Refresh screen with updatedDonor
}
}
所有这些更新的捐助者代码都可以正常工作。现在我的情况是用户可以向捐赠者拨打 phone 电话。在此过程中,我必须更新 Donor 字段以反映最后调用日期。为此,我可以看到两种方法。首先在后台线程中更新 Donor 然后启动一个 Phone Call Intent,或者先启动 Phone Call intent 然后更新 Donor。明智的代码如下
先更新再调用
//Update Donor
DonorEditService editService = new DonorEditService(activity);
donor.setLastCallDate(Calendar.getInstance().getTime());
editService.execute(donor);
//
Intent phoneIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + prefix + donor.getMobileNumber()));
activity.startActivity(phoneIntent);
先调用再更新
Intent phoneIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + prefix + donor.getMobileNumber()));
activity.startActivity(phoneIntent);
//Update Donor
DonorEditService editService = new DonorEditService(activity);
donor.setLastCallDate(Calendar.getInstance().getTime());
editService.execute(donor);
//
幸运或不幸的是,这两个都在模拟器上工作。唯一关心的是,如果调用 activity 不在 OnResume 状态,如何调用 AsyncTask.onPostExecute()。即它被Phone Call Activity 阻塞。另外,哪种方法更好;先编辑再调用;或先致电,然后编辑
编辑:
我刚刚从@Darwind 的评论中意识到我应该展示 DonorEditService 的代码,它实际上是 AsyncTask<DonorBase>
(而不是 android Service)。 DonorBase 是 Donor 的超级 class。
这是 DonoEditService 代码的一部分
public class DonorEditService extends AsyncTask<DonorBase, Void, DonorBase> {
public DonorEditService(Activity activity, boolean displayProgressDialog) {
...
}
@Override
protected void onPreExecute() {
//Show Progress Dialog for Donor Edit process
}
@Override
protected DonorBase doInBackground(DonorBase... donors) {
//Carry out the Http request to Edit Donor on Server
...
}
@Override
protected void onPostExecute(DonorBase updatedDonor) {
//Run on Main UI thread. I invoke AsyncTaskCallback from here
taskCallback.onAsyncTaskCompleted(updatedDonor); //taskCallback is DonorDetailActivity implementing AsyncCallback
...
}
}
好吧,您的问题有很多解决方案。
首先,我建议您不要将 DetailActivity
作为参数传递给 AsyncTask
,因为这会导致泄漏。
起初我认为为您的目的使用 BroadcastReceiver 是个好主意,但后来发现这是行不通的,因为您离开 DetailActivity
并选择 phone打电话,最后可能收不到广播。
相反,我建议您实施 Service,因为您的 Activity
可以 bind
和 unbind
到 Service
并询问有关的信息Service
。这个想法是,即使用户导航离开您的 DetailActivity
,您的 Service
也会 运行,因此可以保留一些数据,直到用户返回您的应用。
然后当用户返回到您的应用并恢复 DetailActivity
时,您只需要再次 "bind" 到 Service
并请求查看是否有任何更改用户不在。
您可以保留 AsyncTask
而不是让 DetailActivity
直接调用它,让 Service
直接调用它,这样 DetailActivity
调用 Service
,这将调用 AsyncTask
。
现在我看到您已经为 DetailActivity
实施了一个 Observer pattern
,以便在 AsyncTask
完成时得到通知。我实际上建议您实现 BroadcastReceiver 而不是这种 "hardly coupled" 观察者模式,因此 AsyncTask
会将 "broadcasts" 发送到 DetailActivity
。现在,当 DetailActivity
暂停时(用户正在拨打 phone),广播将不会被 DetailActivity
接收,但这没关系。仅当用户将您的应用置于 100% 焦点(可见)时才应接收广播。
对不起,文字墙,但这有点像 "advanced" 主题。我希望它对你有帮助,如果没有,我会尝试用一些代码进行扩展:-)
我需要清楚地了解 AsyncTask 处理在我的场景中是如何发生的。我有一个普通的 java 对象,叫做 Donor。
有一个 activity(比如说 DonorDetailActivity)修改了这个供体对象。修改发生在 AsyncTask<>(例如 DonorEditService)中。因此,从 DonorDetailActivity 调用 DonorEditService 在后台线程中编辑 Donor,并将结果发布到主要 UI 线程。
DonorDetailActivity class
public class DonorDetailActivity extends ActionBarActivity implements AsyncTaskCallback<Donor>{
@Override
protected void onCreate(Bundle savedInstanceState) {
btnEditDonor.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) { //Invoke the DonorEditService
DonorEditService editService = new DonorEditService(DonorDetailActivity.this);
editService.execute(donor);
}
});
}
//Invoked from DonorEditService.onPostExecute(DonorBase updatedDonor)
@Override
public void onAsyncTaskCompleted(Donor updatedDonor) {
updateUI(); //Refresh screen with updatedDonor
}
}
所有这些更新的捐助者代码都可以正常工作。现在我的情况是用户可以向捐赠者拨打 phone 电话。在此过程中,我必须更新 Donor 字段以反映最后调用日期。为此,我可以看到两种方法。首先在后台线程中更新 Donor 然后启动一个 Phone Call Intent,或者先启动 Phone Call intent 然后更新 Donor。明智的代码如下
先更新再调用
//Update Donor
DonorEditService editService = new DonorEditService(activity);
donor.setLastCallDate(Calendar.getInstance().getTime());
editService.execute(donor);
//
Intent phoneIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + prefix + donor.getMobileNumber()));
activity.startActivity(phoneIntent);
先调用再更新
Intent phoneIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + prefix + donor.getMobileNumber()));
activity.startActivity(phoneIntent);
//Update Donor
DonorEditService editService = new DonorEditService(activity);
donor.setLastCallDate(Calendar.getInstance().getTime());
editService.execute(donor);
//
幸运或不幸的是,这两个都在模拟器上工作。唯一关心的是,如果调用 activity 不在 OnResume 状态,如何调用 AsyncTask.onPostExecute()。即它被Phone Call Activity 阻塞。另外,哪种方法更好;先编辑再调用;或先致电,然后编辑
编辑:
我刚刚从@Darwind 的评论中意识到我应该展示 DonorEditService 的代码,它实际上是 AsyncTask<DonorBase>
(而不是 android Service)。 DonorBase 是 Donor 的超级 class。
这是 DonoEditService 代码的一部分
public class DonorEditService extends AsyncTask<DonorBase, Void, DonorBase> {
public DonorEditService(Activity activity, boolean displayProgressDialog) {
...
}
@Override
protected void onPreExecute() {
//Show Progress Dialog for Donor Edit process
}
@Override
protected DonorBase doInBackground(DonorBase... donors) {
//Carry out the Http request to Edit Donor on Server
...
}
@Override
protected void onPostExecute(DonorBase updatedDonor) {
//Run on Main UI thread. I invoke AsyncTaskCallback from here
taskCallback.onAsyncTaskCompleted(updatedDonor); //taskCallback is DonorDetailActivity implementing AsyncCallback
...
}
}
好吧,您的问题有很多解决方案。
首先,我建议您不要将 DetailActivity
作为参数传递给 AsyncTask
,因为这会导致泄漏。
起初我认为为您的目的使用 BroadcastReceiver 是个好主意,但后来发现这是行不通的,因为您离开 DetailActivity
并选择 phone打电话,最后可能收不到广播。
相反,我建议您实施 Service,因为您的 Activity
可以 bind
和 unbind
到 Service
并询问有关的信息Service
。这个想法是,即使用户导航离开您的 DetailActivity
,您的 Service
也会 运行,因此可以保留一些数据,直到用户返回您的应用。
然后当用户返回到您的应用并恢复 DetailActivity
时,您只需要再次 "bind" 到 Service
并请求查看是否有任何更改用户不在。
您可以保留 AsyncTask
而不是让 DetailActivity
直接调用它,让 Service
直接调用它,这样 DetailActivity
调用 Service
,这将调用 AsyncTask
。
现在我看到您已经为 DetailActivity
实施了一个 Observer pattern
,以便在 AsyncTask
完成时得到通知。我实际上建议您实现 BroadcastReceiver 而不是这种 "hardly coupled" 观察者模式,因此 AsyncTask
会将 "broadcasts" 发送到 DetailActivity
。现在,当 DetailActivity
暂停时(用户正在拨打 phone),广播将不会被 DetailActivity
接收,但这没关系。仅当用户将您的应用置于 100% 焦点(可见)时才应接收广播。
对不起,文字墙,但这有点像 "advanced" 主题。我希望它对你有帮助,如果没有,我会尝试用一些代码进行扩展:-)