如何将IntentService的结果返回到Activity中?

时间:2012-04-26 13:53:05

标签: android android-intent

我使用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()函数中拉出来会有用吗?是否有另一个/更好的结构代码?非常感谢。

4 个答案:

答案 0 :(得分:82)

您应该在活动中创建自己的ResultReceiver子类。 ResultReceiver实施Parcelable,因此可以ActivityService传递到Intent作为ResultReceiver的额外内容。

你需要做这样的事情:

  1. 在您的活动类中实现onReceiveResult()的子类。实施的关键方法是Bundle。此方法为您提供了Service结果数据,可用于传递您在ResultReceiver中检索的任何信息。只需解压缩您需要的数据并使用它来更新您的活动。

  2. 在您的活动中,创建自定义Intent的新实例,并将其添加到您用于启动服务的Service

  3. onStartCommand()的{​​{1}}方法中,检索ResultReceiver上传入的Intent并将其存储在本地成员变量中。

  4. Service完成其工作后,让它在ResultReceiver上调用send(),将您要发送的任何数据传递回Bundle中的活动。

  5. 这是一个非常有效的模式,意味着你不会将数据存储在令人讨厌的静态变量中。

答案 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是一个开源项目,旨在提供事件总线实现,以便组件可以发布和订阅事件。