为两步任务设计服务

时间:2016-03-07 17:54:23

标签: android android-fragments android-service

我有DialogFragment可以从任何地方发起,我们称之为UploadDialogFragment。该片段允许用户完成两个相关任务:

  1. 上传图片(最多可能需要1分钟)
  2. 使用一些文本和对已保存图像的引用上载JSON对象
  3. 这两项任务需要按顺序完成 - 如果没有完成2.,则无法执行1.。所以真正发生的是:

    • 我开始上传图片(1.
    • 同时,用户编写文本并添加其他信息
    • 当一切准备就绪后,关闭对话框并开始第二项任务(2.)。

    我曾经用后台任务执行此操作,但现在我想切换到Service:即使在解雇后我强行退出应用程序,也应该完成整个操作。

    当前设计

    根据我的经验,我一直使用IntentService,所以我是一个完整的新手。我正在向前推进的当前有缺陷的设计是这样的:

    public class UploadService extends Service {
    
        private final Binder binder = new Binder();
    
        public class Binder extends android.os.Binder {
            UploadService getService() {
                return UploadService.this;
            }
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            return START_NOT_STICKY;
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return binder;
        }
    
        public void completeFirstTask() {
            ...
        }
    
        public void completeSecondTask() {
            // wait for first task to complete if necessary...
            ...
            stopSelf();
        }
    
    }
    

    这是我的UploadDialogFragment

    public class UploadDialogFragment extends AppCompatDialogFragment implements
            ServiceConnection {
    
        private UploadService uploadService;
        private boolean boundService;
    
        @Override
        public void onServiceDisconnected(ComponentName name) {
            uploadService = null;
            boundService = false;
        }
    
        private void bindService() {
            Intent i = new Intent(getActivity().getApplicationContext(), UploadService.class);
            getActivity().getApplicationContext().bindService(i, this, Context.BIND_AUTO_CREATE);
            boundService = true;
        }
    
        private void unbindService() {
            if (boundService) {
                getActivity().unbindService(this);
                boundService = false;
            }
        }
    
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            uploadService = ((UploadService.Binder) service).getService();
            uploadService.completeFirstTask();
        }
    
        // THEN, LATER:
        // OnClick of a button, I call uploadService.completeSecondTask();
        // and this.dismiss();
    
    }
    

    现在这是非常有缺陷的。

    • 当对话框片段被关闭/解散/重新创建时,我需要可靠unbind(),否则我会因ServiceConnection(右边?)而泄漏它。我不知道什么时候开始?。 onDismiss,onDestroyView,onSaveInstanceState ...我尝试了很多选项,但我常常以IllegalArgumentException说服务连接没有注册。

    • 该服务可能永远不会到达completeSecondTask()部分,因此没有人会阻止它,无缘无故地泄露它。 我应该在某个地方调用stopService(),但在哪里?这些是不同的场景:

      1. 我强制退出应用/在completeSecondTask()电话后重新创建片段:服务应继续运行直至结束。

      2. 我在没有调用completeSecondTask()的情况下重新创建了片段:服务应该一直持续到它结束。(我的片段中有适当的逻辑来处理这个)

      3. 我强行退出应用而未调用completeSecondTask()服务应停止。

    问题

    现在,您可能会将此视为两个问题:如何处理unbind()以及如何处理stopService()

    然而,因为我发现很难设置这个小任务,我认为这是非常有缺陷的,我应该使用一种完全不同的方法。我希望你能为我阐明一下。

0 个答案:

没有答案