【问题标题】:Android: get result from a serviceAndroid:从服务中获取结果
【发布时间】:2012-08-29 08:11:28
【问题描述】:

我有 android 服务,我需要在它启动后返回一个结果。 所以:

1) 我启动服务

2) 服务做某事

3) 服务返回结果

我想也许我可以使用单例类来获取结果。我创建了一个单例类,以使服务将结果保存在其中,然后通过活动从服务中获取结果。这是类的代码:

public class Result {

    //SIGLETON DECLARATION

    private static Result mInstance = null;

    public static Result getInstance() { 
        if (mInstance == null) {
            mInstance = new Result();
        }
        return mInstance;
    }

    private Result() {
    }

    //CODE

    Object result;
    boolean resultIsSet = false;

    public void deletePreviousResult() {
        this.result = null;
        resultIsSet = false;
    }

    public void setResult(Object result) {
        Log.w("result", "setResult");
        this.result = result;
        resultIsSet = true;
    }

    public Object getResult() {
        Log.w("result", "getResult");
        while(resultIsSet == false) {}
        return this.result;
    }

这是我用来获取结果的代码:

public int getInfo() {
    Result.getInstance().deletePreviousResult();
    //start the service and ask to save the result in singleton class
    Intent myIntent = new Intent(mInstanceContext, MediaPlayerService.class);
    myIntent.setAction("getInfo");
    mInstanceContext.startService(myIntent);
    //take the result
    return (Integer) Result.getInstance().getResult();
}

onStartCommand 的作用是:

 Result.getInstance().setResult(mMediaPlayer.getCurrentPosition()); 

mMediaPlayer 是一个 MediaPlayer 对象。

但是问题是如果setResult 也应该在onStartCommand 中被调用,那么它永远不会被调用!为什么?是不是我的方法不对?

【问题讨论】:

  • 你能分享你的 onStartCommand 的代码吗?
  • 当然,它的作用是这样的:Result.getInstance().setResult(mMediaPlayer.getCurrentPosition());其中 mMediaPlayer 是一个 MediaPlayer 对象;)
  • 只是为了交叉检查,您是否在清单中声明了服务?您的服务扩展了 Service 或 IntentService 或任何其他基类?
  • 它扩展了服务并声明了:)

标签: android service return


【解决方案1】:

这个代码你在getInfo():

mInstanceContext.startService(myIntent);
//take the result
return (Integer) Result.getInstance().getResult();

假设当您调用startService() 时服务已启动并且onStartCommand() 被同步调用,因此在下一条语句中您可以使用Result.getInstance().getResult() 获得结果。

不幸的是,它不是那样工作的。调用startService() 不像调用对象的方法。当您致电 startService() 时,您所做的是告诉 Android 您希望该服务在在下一个可用时刻启动。由于您的服务中的onStartCommand()需要在主线程上调用,通常这意味着Android将在下次Android获得主线程控制权时(即:当您的所有活动方法时)启动您的服务并调用onStartCommand()已返回)。在任何情况下,您都无法确定何时启动服务或何时调用onStartCommand()。这是一个异步调用,所以你需要依赖一个callback机制。这意味着您需要编写某种回调方法,服务可以在它完成工作并希望将结果返回给您时调用。

有多种方法可以做到这一点。您可以让服务向您的活动发送 Intent。您可以让服务广播带有结果的 Intent。您可以绑定到服务并注册回调侦听器(请参阅绑定服务的开发人员文档)。可能还有其他方法。

【讨论】:

  • 添加到您提到的内容中,'return (Integer) Result.getInstance().getResult();'导致无限循环,因为“getResult()”检查“resultIsSet”是否为真;只有这样它才会返回“结果”的值。现在,有趣的是,可以在服务的“onStartCommand”中将“resultIsSet”设置为 true。但是服务在其应用程序的主线程中运行,并且应用程序当前在“getResult()”中无限循环。所以这是一种僵局。这就是回调的用武之地。服务可以广播意图,而不是无限地检查循环。
  • 您可以在后台线程中运行 getResult(),这样它就不会阻止主线程运行您的服务。这样事情就简单了?
猜你喜欢
  • 2018-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多