Android 如何将 IntentService 的结果返回到 Activity 中?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10334901/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get results from an IntentService back into an Activity?
提问by gcl1
I am using an IntentService to handle network communications with a server via JSON. The JSON/server part is working fine, but I'm having trouble getting the results back where they are needed. The following code shows how I am starting the intent service from inside onClick(), and then having the service update a global variable to relay the results back to the main activity.
我正在使用 IntentService 通过 JSON 处理与服务器的网络通信。JSON/服务器部分工作正常,但我无法将结果返回到需要的地方。以下代码显示了我如何从 onClick() 内部启动意图服务,然后让服务更新全局变量以将结果中继回主活动。
public class GXActivity extends Activity {
private static final String TAG = "GXActivity";
@Override
public void onCreate(Bundle savedInstanceState) {
// === called when the activity is first created
Log.i(TAG, "GXActivity Created");
super.onCreate(savedInstanceState);
setContentView(R.layout.start);
View.OnClickListener handler = new View.OnClickListener() {
public void onClick(View v) {
// === set up an application context to hold a global variable
// === called user, to contain results from the intent service
GXApp appState = ((GXApp) getApplicationContext());
User user = new User(-1); // initialize user id to -1
appState.setUser(user);
// === next start an intent service to get JSON from the server;
// === this service updates the user global variable with
// === results from the JSON transaction
Intent intent = new Intent(this, GXIntentService.class);
startService(intent);
// === check app context for results from intent service
appState = ((GXApp) getApplicationContext());
if (appState.getUser().getId() != -1)...
}
}
}
}
The problem I'm having is that the intent service that parses the JSON doesn't get invoked until after onCreate() completes, so my code that's looking for the results is stuck looking at uninitialized results.
我遇到的问题是解析 JSON 的意图服务直到 onCreate() 完成后才会被调用,所以我正在寻找结果的代码在查看未初始化的结果时被卡住了。
What should I do differently so the intent service gets called before I check the results? Would it work if I pulled the click listener out of the onCreate() function? Is there a another/better to structure this code? Many thanks.
我应该怎么做才能在检查结果之前调用 Intent 服务?如果我从 onCreate() 函数中拉出点击侦听器,它会起作用吗?是否有另一个/更好的结构此代码?非常感谢。
回答by tomtheguvnor
You should look at creating your own ResultReceiver
subclass in your activity. ResultReceiver
implements Parcelable
so can be passed from your Activity
to your Service
as an extra on the Intent
.
您应该考虑ResultReceiver
在您的活动中创建您自己的子类。ResultReceiver
实现Parcelable
因此可以从您的传递Activity
到您的Service
作为Intent
.
You'll need to do something like this:
你需要做这样的事情:
Implement a subclass of
ResultReceiver
within your activity class. The key method to implement isonReceiveResult()
. This method provides you a withBundle
of result data which can be used to pass whatever information you are retrieving in yourService
. Simply unpack the data you need and use it to update your activity.In your activity, create a new instance of your custom
ResultReceiver
and add it to theIntent
you use to start your service.In your
Service
'sonStartCommand()
method, retrieve theResultReceiver
passed in on theIntent
and store it in a local member variable.Once your
Service
completes its work, have it callsend()
on the ResultReceiver passing whatever data you want to send back to the activity in aBundle
.
ResultReceiver
在您的活动类中实现一个子类。实现的关键方法是onReceiveResult()
. 此方法为您提供了一个Bundle
结果数据,可用于传递您在Service
. 只需解压缩您需要的数据并使用它来更新您的活动。在您的活动中,创建自定义的新实例
ResultReceiver
并将其添加到Intent
用于启动服务的 。在您
Service
的onStartCommand()
方法中,检索ResultReceiver
传入的Intent
并将其存储在本地成员变量中。一旦你
Service
完成了它的工作,让它调用send()
ResultReceiver 将你想要发送回活动的任何数据传递给Bundle
.
This is a pretty effective pattern and means you're not storing data in nasty static variables.
这是一种非常有效的模式,意味着您不会将数据存储在讨厌的静态变量中。
回答by DSoldo
There's many ways to do stuffs in background getting back a result (AsyncTask, bind an Activity to a Service...), but if you want to mantain your IntentService's code you can simply:
有很多方法可以在后台做一些事情来获取结果(AsyncTask,将一个活动绑定到一个服务......),但是如果你想维护你的 IntentService 的代码,你可以简单地:
1- send a broadcast intent (that contains the status in its extended data) at the end of the work in your IntentService
1- 在您的 IntentService 工作结束时发送广播意图(包含其扩展数据中的状态)
2- implement a LocalBroadcastReceiver in your Activity that consumes the data from the Intent
2- 在您的 Activity 中实现一个 LocalBroadcastReceiver 来消耗来自 Intent 的数据
This is also the recommended way in the official documentation (if you want to mantain your IntentService):
这也是官方文档中推荐的方式(如果你想维护你的 IntentService):
https://developer.android.com/training/run-background-service/report-status.html
https://developer.android.com/training/run-background-service/report-status.html