需要一些帮助来理解这个AsyncTask场景

时间:2015-01-01 06:32:31

标签: java android android-asynctask

我需要清楚地了解在我的场景中AsyncTask处理将如何发生。我有一个名为 Donor 的普通java对象。

有一项活动(比如说 DonorDetailActivity )会修改此捐赠对象。修改发生在 AsyncTask<> (例如 DonorEditService )中。因此,从 DonorDetailActivity 调用 DonorEditService ,在后台线程中编辑 Donor ,并将结果发布到主UI线程。

DonorDetailActivity类

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
    }
}

所有这些更新Donor代码都能正常工作。现在我的情况是用户可以打电话给捐赠者。在此过程中,我必须更新捐赠者的字段以反映最后调用日期。为此,我可以看到两种方式。首先在后台线程中更新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);
//

幸运或不幸的是,这些都在模拟器上运行。唯一的问题是如果调用活动不在 OnResume 状态,如何调用 AsyncTask.onPostExecute()。也就是说,它被电话呼叫活动阻止。另外,哪种方法更好;先编辑并调用;或先打电话和编辑

编辑:

我刚从@Darwind的评论中意识到我应该展示 DonorEditService 的代码,实际上是AsyncTask<DonorBase>(而不是android Service)。 DonorBase是捐赠者的超级类。

以下是 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
        ...
    }
}

1 个答案:

答案 0 :(得分:0)

您的问题有很多解决方案。

首先,我建议您不要将DetailActivity作为参数传递给AsyncTask,因为这会导致泄密。

起初我认为使用BroadcastReceiver为您的目的是个好主意,但是想通了,这不会有用,因为您离开了DetailActivity并拨打了电话,可能不会最终得到广播。

相反,我建议您实施Service,因为Activity bind可以unbind Service Service,并询问有关Service的信息1}}。我们的想法是,即使用户离开您的DetailActivity,您的DetailActivity仍会运行,因此可以保留一些数据,直到用户返回您的应用为止。

然后,当用户返回您的应用并恢复Service时,您只需再次“绑定”到AsyncTask并请求查看在用户离开时是否有更改的内容

您可以保留DetailActivity而不是让Service直接呼叫它,让DetailActivity直接呼叫它,以便Service呼叫AsyncTask这将调用Observer pattern

现在,当DetailActivity完成时,我发现AsyncTask已为AsyncTask实施了DetailActivity。我实际上建议您实施BroadcastReceiver,而不是这种“几乎不耦合”的观察者模式,因此DetailActivity会向DetailActivity发送“广播”。现在当{{1}}暂停(用户正在拨打电话)时,{{1}}将无法接听广播,但这很好。只有当用户将您的应用程序置于100%焦点(可见)时,才能选择广播。

对于文字墙感到抱歉,但这有点像“高级”主题。我希望它可以帮助你,如果没有,我会尝试扩展一些代码: - )