好的,我一直在研究解决这个问题的最佳方法,所以让我为你分解我的需求和发现。
需要:
这里的最后一颗子弹是最难的。
结果:
我想过只是在静态AsyncTask中完成这项工作,但我认为这对我不起作用 - 状态变得非常混乱,似乎我无法保证操作系统在应用程序出现时不会杀死线程在后台。
我决定使用一个服务,在服务中创建它并绑定/解除绑定。该服务生成AsyncTask,完成工作,然后根据其结果(SUCCEED / FAIL)发出活动信号。除了我的大消息之外,这种范例似乎工作正常。服务/活动通信消息通信不是用于编组这样大的有效载荷。 *注意:如果不清楚,当用户点击发送时,该表格数据和文件必须提供给服务。在某些情况下,这是从相机拍摄的图像,该图像不能并且不能存在于磁盘上以用于应用程序。
显然我想要的是某种共享内存存储,我可以从Activity中保存数据。然后,活动可以通知服务它可以继续并上传该数据。
内存中是否存在这样的共享区域?我可以从服务获取Application对象并将数据存储在那里吗?
另一个问题出现在上传完成但没有活动绑定到服务但是我想我可能已经想出了这个。如果以下内容有意义,请告诉我:
答案 0 :(得分:4)
为了处理你的内存需求,我可能会将Map
UUID用于包含所有消息详细信息的持有者类。将此Map
存储为Application
子类中的成员变量,或者作为静态变量。当您的任务完成或失败时,确保将其清除。如果您确定不会同时有多个此类请求,也许您可以使用单个类而不是Map或列表。
然后,您可以在IntentService的帮助下使用WakeLock来完成您的要求。我倾向于避免在Android中绑定服务,因为它们很难用于屏幕旋转。只需从启动IntentService
的Intent中的Map传递标识符。
在我看来,从服务回复到您的活动的最佳方式是使用PendingIntent
。基本上,您从Activity启动服务,并在启动服务的Intent中传入PendingIntent
。当您的服务完成其工作或失败后,您可以在PendingIntent上调用send()
。然后,您的Activity将在其onActivityResult()
方法中获得回调。
这样做有几个好处:
IntentService
中的单独线程中完成一个长时间运行的任务,并在UI线程完成时收到通知。onActivityResult()
中获得回调。相反,即使你finish()
你的活动并在发送PendingIntent之前开始一个新活动,它也不会被传递,这几乎总是你想要的。我有一个显示此方法的demo application。基本上,你有一个Activity明星有些工作,并通过进度对话框阻止UI。如果屏幕旋转,将再次显示此对话框。该工作在Service完成,该nice example将PendingIntent
发送回活动。
您的工作的最后一部分是确保设备在上传运行时不会进入休眠状态。 Mark Murphy编写了Service implementation和{{3}},使用WakeLock
来确保工作不间断地完成。
答案 1 :(得分:1)
首先,您还应该将服务切换到通过startService()
调用触发的前台服务(而不是绑定到服务)。这将确保服务尽可能长时间保持活力。绑定到服务将在您的活动完成后停止服务(这可能在用户离开您的应用时发生)。
我还会利用前台服务使用的通知让用户知道他们上传的状态。
要将信息从服务传递回Activity,您可以查看ResultReceiver类。具体来说,研究一下Google在其IO应用程序中实现的DetachableResultReceiver范例。
由于除了通信要求之外还有大量内存要求,您可能只想创建一个单例对象来共享活动和服务之间的数据和状态。
答案 2 :(得分:0)
使用静态变量创建一个类,并让您的活动将所有值设置为该类。然后启动一个IntentService并让该服务查看上面的类。一旦IntentService处理完该消息,它就会广播该消息,如果有任何活动在等待广播,他们将收到该消息。