势必服务与启动服务在Android上,如何做到既 [英] bound service versus started service on Android and how to do both

查看:177
本文介绍了势必服务与启动服务在Android上,如何做到既的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我问已经(部分,在我看来)一个棘手的问题解决<一href="http://stackoverflow.com/questions/5243562/lifecycle-of-service-that-is-started-and-bound">here和<一href="http://stackoverflow.com/questions/3514287/android-service-startservice-and-bindservice">here.比方说,像在许多例子中,我们要创建一个音乐应用程序,使用(比如)一个单一的活动和服务。我们希望在活动已停止或销毁服务坚持。这种生命周期提出了一个启动的服务:

  

一个服务的启动当应用程序组件(如   活动)通过调用startService启动它()。一旦开始,一个服务   可以在后台运行下去,即使该组件   开始它被摧毁

好了,但我们也希望能够与该服务进行沟通,所以我们需要一个服务绑定。没问题,我们有两个绑定,并开始服务为这个答案意味着

  • 在活动启动(或一些其他点),我们称之为<一href="http://developer.android.com/reference/android/content/Context.html#startService%28android.content.Intent%29">startService()
  • 在我们称之为<一href="http://developer.android.com/reference/android/content/Context.html#bindService%28android.content.Intent,%20android.content.ServiceConnection,%20int%29">bindService()获得的IBinder 接口,并从那里继续。

到目前为止好,但一个问题是由以下事实的活动开始时,我们不知道,如果服务是周围或没有。它可能已被启动,也可能不会有。答案可能是这样的:

  • 在启动时,尝试绑定到该服务(使用<一个href="http://developer.android.com/reference/android/content/Context.html#bindService%28android.content.Intent,%20android.content.ServiceConnection,%20int%29">bindService()没有<一href="http://developer.android.com/reference/android/content/Context.html#BIND_AUTO_CREATE">BIND_AUTO_CREATE标志)
  • 如果失败,则使用启动服务 startService(),然后绑定到它。

这个想法是pmised对文档的特定读物 bindService($ P $)

  

连接到一个应用服务,如果需要的话在创建它。

如果零标志的意思是服务是不是真的需要比我们好。因此,我们尝试这样的事情使用下面的code:

 私人无效connectToService(){
    Log.d(MainActivity,连接到服务);
    //我们尝试绑定到现有服务
    意图bindIntent =新的意图(这一点,AccelerometerLoggerService.class);
    布尔bindResult = bindService(bindIntent,mConnection,0);
    如果(bindResult){
        //服务存在的,所以我们只是绑定到它
        Log.d(MainActivity,找到一个pre-现有服务,并绑定了);
    } 其他 {
        Log.d(MainActivity,无pre-现有服务入手一部);
        //服务是不存在的,所以我们必须启动

        意图startIntent =新的意图(这一点,AccelerometerLoggerService.class);
        组件名startResult = startService(startIntent);
        如果(startResult == NULL){
            Log.e(MainActivity,无法启动我们的服务);
        } 其他 {
            Log.d(MainActivity,启动的服务将绑定);
            //现在,该服务已启动,我们可以给它绑定
            bindService(bindIntent,mConnection,0);
            如果(!bindResult){
                Log.e(MainActivity,启动的服务,然后没有绑定到它);
            } 其他 {
                Log.d(MainActivity,绑定成功);
            }
        }
    }
}
 

和我们得到的是一个成功的绑定,每次:

  5月4日至23日:42:59.125:D / MainActivity(842):连接到服务
5月4日至23日:42:59.125:D / MainActivity(842):发现了pre-现有服务,并绑定到它
5月4日至23日:42:59.134:D / MainActivity(842):的onCreate
 

全球问题是:我误解约束与启动服务,以及如何使用它们?更具体的问题是:

  • 这是不是正确的认识文档中认为,零标志传递给 bindService()表示不启动服务?如果没有,有没有办法来调用 bindService()不启动服务?
  • 为什么 bindService()返回即使服务没有运行?在这种情况下,它看起来像服务不已经开始,根据登录的电话。
  • 如果在那里的previous点的正确/预期的行为bindService(),有没有一种解决方法(即一定程度上保证 startService 被称为只有当服务没有运行?)

P.S。我从这个问题在我自己的code移动了:我发出 startService()来电不管,因为重复 startService()被简单地忽略。不过,我仍想了解这些问题越好。

解决方案
  1. 如果您bindService 0标志,那么该服务将无法启动。可以用BIND_AUTO_CREATE标志bindService并且如果未启动该服务,它就会被启动。但是,当您unbindService的服务将被破坏。
  2. bindService 0标志总是返回true。
  3. 您可以随时调用startService。如果该服务已经然后运行新的服务将不会被创建。正在运行的服务onStartCommand将被调用。

不应有任何问题,如果你startService中的onCreate然后bindService在onResume和unbindService中的onPause。

I am asking a vexed question that has been (partially, to my mind) addressed here and here. Let's say like in many examples we want to create a music application, using (say) a single activity and a service. We want the service to persist when the Activity is stopped or destroyed. This kind of lifecycle suggests a started service:

A service is "started" when an application component (such as an activity) starts it by calling startService(). Once started, a service can run in the background indefinitely, even if the component that started it is destroyed

Ok, but we also want to be able to communicate with the service, so we need a service binding. No problem, we have both a bound and started service as this answer suggests:

So far so good, but a problem arises from the fact that when the activity starts, we do not know if the service is around or not. It may have been started or it may not have been. The answer could be something like:

  • At startup, try to bind to the service (use bindService() without the BIND_AUTO_CREATE flag)
  • If that fails, then start the service using startService(), and then bind to it.

This idea is premised on a particular reading of the docs for bindService():

Connect to an application service, creating it if needed.

If zero flag means "service is not really needed" than we are OK. So we try something like this using the following code:

private void connectToService() {
    Log.d("MainActivity", "Connecting to service");
    // We try to bind to an existing service
    Intent bindIntent = new Intent(this, AccelerometerLoggerService.class);
    boolean bindResult = bindService(bindIntent, mConnection, 0);
    if (bindResult) {
        // Service existed, so we just bound to it
        Log.d("MainActivity", "Found a pre-existing service and bound to it");
    } else {
        Log.d("MainActivity", "No pre-existing service starting one");
        // Service did not exist so we must start it

        Intent startIntent = new Intent(this, AccelerometerLoggerService.class);
        ComponentName startResult = startService(startIntent);
        if (startResult==null) {
            Log.e("MainActivity", "Unable to start our service");
        } else {
            Log.d("MainActivity", "Started a service will bind");
            // Now that the service is started, we can bind to it
            bindService(bindIntent, mConnection, 0);
            if (!bindResult) {
                Log.e("MainActivity", "started a service and then failed to bind to it");
            } else {
                Log.d("MainActivity", "Successfully bound");
            }
        }
    }
}

And what we get is a successful binding every time:

04-23 05:42:59.125: D/MainActivity(842): Connecting to service
04-23 05:42:59.125: D/MainActivity(842): Found a pre-existing service and bound to it
04-23 05:42:59.134: D/MainActivity(842): onCreate

The global question is "Am I misunderstanding bound versus started services and how to use them?" More specific questions are:

  • Is it the correct understanding of the docs to think that zero flag passed to bindService() means "Do not start the service"? If not, is there no way to call bindService() without starting the service?
  • Why does bindService() return true even if the service is not running? In this case it doesn't seem like the service has been started, based on Log calls.
  • If there the previous point is the correct/expected behavior of bindService(), is there a workaround (i.e. somehow ensure that startService is called only if the service is not running?)

P.S. I've moved on from the problem in my own code: I issue startService() calls regardless, since repeated startService() are simply ignored. However, I would still like to understand the issues better.

解决方案

  1. If you bindService with 0 flag then the service will not start. You can bindService with BIND_AUTO_CREATE flag and if the service is not started, it will be started. However, when you unbindService the service will be destroy.
  2. bindService with 0 flag always returns true.
  3. You can always call startService. If the service is already running then a new service will not be created. The running service onStartCommand will be called.

There should not be any problem if you startService in onCreate and then bindService in onResume and unbindService in onPause.

这篇关于势必服务与启动服务在Android上,如何做到既的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆