如何通过片段获得有关异步任务结果的通知?

我有一个使用片段的Activity。 根据用户的交互,这些片段可能来来去去。 许多这些片段将作业发送到IntentService,这样就可以以异步方式运行。 IntentService应该如何报告这些工作的结果?

启动作业的片段可能不存在。 如果作业完成且起始片段当前处于活动状态,则应该收到相关通知,并采取相应措施。 如果不是,那么就不需要采取任何行动。

我曾考虑使用广播意图和BroadcastReceiver组件,但片段不能注册接收者,只能注册活动。

你会建议什么解决方案?

我在IOSched App (适用于Android的Google I / O应用程序)中注意到了同样的问题。

他们创建了DetachableResultReceiver ,它扩展了SDK类ResultReciever 。

他们很容易在Fragments中使用它 。

接收器:

/** * Proxy {@link ResultReceiver} that offers a listener interface that can be * detached. Useful for when sending callbacks to a {@link Service} where a * listening {@link Activity} can be swapped out during configuration changes. */ public class DetachableResultReceiver extends ResultReceiver { private static final String TAG = "DetachableResultReceiver"; private Receiver mReceiver; public DetachableResultReceiver(Handler handler) { super(handler); } public void clearReceiver() { mReceiver = null; } public void setReceiver(Receiver receiver) { mReceiver = receiver; } public interface Receiver { public void onReceiveResult(int resultCode, Bundle resultData); } @Override protected void onReceiveResult(int resultCode, Bundle resultData) { if (mReceiver != null) { mReceiver.onReceiveResult(resultCode, resultData); } else { Log.w(TAG, "Dropping result on floor for code " + resultCode + ": " + resultData.toString()); } } } 

活动和片段:

 public class HomeActivity extends BaseActivity { private static final String TAG = "HomeActivity"; private SyncStatusUpdaterFragment mSyncStatusUpdaterFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //... mTagStreamFragment = (TagStreamFragment) fm.findFragmentById(R.id.fragment_tag_stream); mSyncStatusUpdaterFragment = (SyncStatusUpdaterFragment) fm .findFragmentByTag(SyncStatusUpdaterFragment.TAG); if (mSyncStatusUpdaterFragment == null) { mSyncStatusUpdaterFragment = new SyncStatusUpdaterFragment(); fm.beginTransaction().add(mSyncStatusUpdaterFragment, SyncStatusUpdaterFragment.TAG).commit(); triggerRefresh(); } } private void triggerRefresh() { final Intent intent = new Intent(Intent.ACTION_SYNC, null, this, SyncService.class); intent.putExtra(SyncService.EXTRA_STATUS_RECEIVER, mSyncStatusUpdaterFragment.mReceiver); startService(intent); if (mTagStreamFragment != null) { mTagStreamFragment.refresh(); } } /** * A non-UI fragment, retained across configuration changes, that updates its activity's UI * when sync status changes. */ public static class SyncStatusUpdaterFragment extends Fragment implements DetachableResultReceiver.Receiver { public static final String TAG = SyncStatusUpdaterFragment.class.getName(); private boolean mSyncing = false; private DetachableResultReceiver mReceiver; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); mReceiver = new DetachableResultReceiver(new Handler()); mReceiver.setReceiver(this); } /** {@inheritDoc} */ public void onReceiveResult(int resultCode, Bundle resultData) { HomeActivity activity = (HomeActivity) getActivity(); if (activity == null) { return; } switch (resultCode) { case SyncService.STATUS_RUNNING: { mSyncing = true; break; } //... } activity.updateRefreshStatus(mSyncing); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); ((HomeActivity) getActivity()).updateRefreshStatus(mSyncing); } } }