android service 异步,在Android的IntentService中等待异步回调

我有一个IntentService ,它在另一个类中启动异步任务,然后应该等待结果。

问题是一旦onHandleIntent(...)方法运行完毕, IntentService就会完成,对吧?

这意味着,通常, IntentService将在启动异步任务后立即关闭,并且不再存在以接收结果。

public class MyIntentService extends IntentService implements MyCallback { public MyIntentService() { super("MyIntentService"); } @Override protected final void onHandleIntent(Intent intent) { MyOtherClass.runAsynchronousTask(this); } } public interface MyCallback { public void onReceiveResults(Object object); } public class MyOtherClass { public void runAsynchronousTask(MyCallback callback) { new Thread() { public void run() { // do some long-running work callback.onReceiveResults(...); } }.start(); } }

如何使上面的代码段工作? 我已经尝试在启动任务后将Thread.sleep(15000) (任意持续时间)放在onHandleIntent(...) 。 它似乎工作。

但它绝对不是一个干净的解决方案。 也许甚至有一些严重的问题。

更好的解决方案?

使用标准Service类而不是IntentService ,从onStartCommand()回调启动异步任务,并在收到完成回调时销毁Service 。

这样做的问题是,如果在Service已经运行时再次启动Service ,则在同时运行任务的情况下正确处理Service的销毁。 如果您需要处理这种情况,那么您可能需要设置一个运行计数器或一组回调,并且只有在它们全部完成时才销毁Service 。

我同意corsair992,通常你不必从IntentService进行异步调用,因为IntentService已经在工作线程上完成了它的工作。 但是,如果必须这样做,则可以使用CountDownLatch 。

public class MyIntentService extends IntentService implements MyCallback { private CountDownLatch doneSignal = new CountDownLatch(1); public MyIntentService() { super("MyIntentService"); } @Override protected final void onHandleIntent(Intent intent) { MyOtherClass.runAsynchronousTask(this); doneSignal.await(); } } @Override public void onReceiveResults(Object object) { doneSignal.countDown(); } public interface MyCallback { public void onReceiveResults(Object object); } public class MyOtherClass { public void runAsynchronousTask(MyCallback callback) { new Thread() { public void run() { // do some long-running work callback.onReceiveResults(...); } }.start(); } }

如果您仍在寻找使用Intent Service进行异步回调的方法,您可以在线程上等待并通知如下,

private Object object = new Object(); @Override protected void onHandleIntent(Intent intent) { // Make API which return async calback. // Acquire wait so that the intent service thread will wait for some one to release lock. synchronized (object) { try { object.wait(30000); // If you want a timed wait or else you can just use object.wait() } catch (InterruptedException e) { Log.e("Message", "Interrupted Exception while getting lock" + e.getMessage()); } } } // Let say this is the callback being invoked private class Callback { public void complete() { // Do whatever operation you want // Releases the lock so that intent service thread is unblocked. synchronized (object) { object.notifyAll(); } } }

我最喜欢的选择是暴露两个类似的方法,例如:

public ListgetDogsSync(); public void getDogsAsync(DogCallback dogCallback);

然后执行如下:

public ListgetDogsSync() { return database.getDogs(); } public void getDogsAsync(DogCallback dogCallback) { new AsyncTask>() { @Override protected ListdoInBackground(Void... params) { return getDogsSync(); } @Override protected void onPostExecute(Listdogs) { dogCallback.success(dogs); } }.execute(); }

然后在您的IntentService您可以调用getDogsSync()因为它已经在后台线程上。

你注定没有改变MyOtherClass 。

通过更改该课程,您有两种选择:

进行同步通话。 IntentService已经为您生成了一个后台Thread 。

在runAsynchronousTask()返回新创建的Thread并在其上调用join() 。

我同意,直接使用Service而不是IntentService可能更有意义,但是如果你使用的是Guava ,你可以将AbstractFuture实现为你的回调处理程序,它可以让你方便地忽略同步的细节:

public class CallbackFuture extends AbstractFutureimplements MyCallback { @Override public void onReceiveResults(Object object) { set(object); } // AbstractFuture also defines `setException` which you can use in your error // handler if your callback interface supports it @Override public void onError(Throwable e) { setException(e); } }

AbstractFuture定义了get() ,它们阻塞直到调用set()或setException()方法,并分别返回一个值或引发一个exception。

然后你的onHandleIntent变成:

@Override protected final void onHandleIntent(Intent intent) { CallbackFuture future = new CallbackFuture(); MyOtherClass.runAsynchronousTask(future); try { Object result = future.get(); // handle result } catch (Throwable t) { // handle error } }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值