2012-09-04 63 views
1

我打开一个新问题更清楚:) 我有android服务,我需要返回一个结果后,它已经开始。 所以: 1)我开始服务 2)服务做些什么 3)服务返回结果 我想也许我可以使用单例类来取得结果。因此,我创建了一个单例类,以便使服务将结果保存在其中,并从活动的服务中获取结果。这里有类的代码:Android:从服务中获取结果

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中调用,它永远不会被调用!为什么?我的方法错了吗? 提前谢谢!

+0

你可以分享onStartCommand的代码吗? – sandyiscool

+0

当然,它所做的是: Result.getInstance()。setResult(mMediaPlayer.getCurrentPosition()); 其中mMediaPlayer是一个MediaPlayer对象;) – user1315621

+0

只是为了进行交叉检查,您是否在manifest中声明了该服务?您的服务扩展了哪些基类Service或IntentService或其他? – vikas

回答

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()。它是一个异步调用,所以你需要依靠一个回调机制。这意味着您需要编写某种回调方法,服务可以在完成工作后调用并且想要将结果返回给您。

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

+0

添加到你所提到的,'返回(整数)Result.getInstance()。的getResult();”导致无限循环,因为'getResult()'检查'resultIsSet'是否为真;只有这样它才会返回'结果'的值。现在,有趣的部分是,'resultIsSet'可以在服务的'onStartCommand'中设置为true。但是一个服务在其应用程序的主线程中运行,并且该应用程序目前正在'getResult()'中循环无限。所以这是一种僵局。这是回调进来的地方。服务可以无限制地检查循环,而不是无限循环地播放意图。 – sandyiscool

+0

您可能可以在后台线程中运行getResult(),以便它不会阻止主线程运行您的服务。这样的事情保持简单? – 3c71