我使用IntentService通过JSON处理与服务器的网络通信。 JSON /服务器部分工作正常,但我无法将结果返回到需要的地方。以下代码显示了我如何从onClick()内部启动intent服务,然后让服务更新一个全局变量以将结果传递回主活动。
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)...
}
}
}
}
我遇到的问题是,在onCreate()完成之后,解析JSON的意图服务不会被调用,所以我的代码查找结果时看到了未初始化的结果。
我应该做些什么,以便在检查结果之前调用intent服务?如果我将click侦听器从onCreate()函数中拉出来会有用吗?是否有另一个/更好的结构代码?非常感谢。
答案 0 :(得分:82)
您应该在活动中创建自己的ResultReceiver
子类。 ResultReceiver
实施Parcelable
,因此可以Activity
从Service
传递到Intent
作为ResultReceiver
的额外内容。
你需要做这样的事情:
在您的活动类中实现onReceiveResult()
的子类。实施的关键方法是Bundle
。此方法为您提供了Service
结果数据,可用于传递您在ResultReceiver
中检索的任何信息。只需解压缩您需要的数据并使用它来更新您的活动。
在您的活动中,创建自定义Intent
的新实例,并将其添加到您用于启动服务的Service
。
在onStartCommand()
的{{1}}方法中,检索ResultReceiver
上传入的Intent
并将其存储在本地成员变量中。
在Service
完成其工作后,让它在ResultReceiver上调用send()
,将您要发送的任何数据传递回Bundle
中的活动。
这是一个非常有效的模式,意味着你不会将数据存储在令人讨厌的静态变量中。
答案 1 :(得分:11)
有很多方法可以在后台获取结果(AsyncTask,将一个Activity绑定到一个服务......),但是如果你想保留你的IntentService代码,你可以简单地:
1-在IntentService工作结束时发送广播意图(包含其扩展数据中的状态)
2-在您的Activity中实现一个使用Intent
中的数据的LocalBroadcastReceiver这也是官方文档中推荐的方式(如果你想保留你的IntentService):
https://developer.android.com/training/run-background-service/report-status.html
答案 2 :(得分:7)
如果你需要做的只是从服务器获取JSON而不锁定UI线程,那么使用AsyncTask可能更简单。
答案 3 :(得分:1)
您可以使用Otto库。 Otto是一个开源项目,旨在提供事件总线实现,以便组件可以发布和订阅事件。