即使有活动客户端,Service.onUnbind()也会被调用?

时间:2012-05-20 18:52:21

标签: android android-service

练习的重点是:保持服务的活力,将其从一个活动传递到另一个活动。

  1. 活动A在服务S上调用bindService();
  2. S.onBound()调用;
  3. 调用A.serviceConnection.onServiceConnected();
  4. 活动A开始活动B;
  5. 活动B在服务S上调用bindService();
  6. 调用B.serviceConnection.onServiceConnected(); 5a:来自onServiceConnected()活动B调用A.finish();
  7. 活动A正在停止,从其onDestroy()方法调用unbindService(S)。
  8. 预期行为:服务S继续幸福地存在,直到活动B调用unbindService()

    实际行为:

    1. 调用S.onUnbind();
    2. 调用S.onDestroy();
    3. B.serviceConnection.onServiceDisconnected()被调用;
    4. 因此破坏了链接并与文档相矛盾。

      为什么呢?我错过了什么?

      更新:已解决。来自http://developer.android.com/reference/android/app/Service.html

        

      服务既可以启动,也可以绑定连接。在   在这种情况下,系统只要保持服务运行   要么已经启动,要么与有一个或多个连接   Context.BIND_AUTO_CREATE标志

      以下是代码:

      public class A extends Activity {
      
          private final Logger logger = LoggerFactory.getLogger(getClass().getSimpleName());
      
          private String serviceClassName;
          private ServiceConnection feedConnection;
          private Messenger feedMessenger;
      
          private void bind(String argument) {
      
              serviceClassName = TheService.class.getName();
              Intent intent = new Intent(serviceClassName);
      
              intent.putExtra(Keys.ACCOUNT, argument);
      
              feedConnection = new FeedConnection();
      
              if (!bindService(intent, feedConnection, Context.BIND_AUTO_CREATE)) {
                  throw new IllegalStateException("Failed to bind to " + argument);
              }
      
              logger.debug("bindService(" + serviceClassName + ") successful");
          }
      
          private void forward() {
      
              Intent intentB = new Intent();
      
              intentB.setClassName(B.class.getPackage().getName(), B.class.getName());
              intentB.putExtra(Keys.SERVICE_CLASS_NAME, serviceClassName);
      
              startActivity(intentB);
          }
      
          @Override
          protected void onDestroy() {
              super.onDestroy();
      
              unbindService(feedConnection);
          }
      
      
          private class FeedConnection implements ServiceConnection {
      
              @Override
              public void onServiceConnected(ComponentName className, IBinder service) {
      
                  A.this.feedMessenger = new Messenger(service);
              }
      
              @Override
              public void onServiceDisconnected(ComponentName className) {
      
                  A.this.feedMessenger = null;
                  logger.error("Crashed " + Integer.toHexString(hashCode()));
              }
          }
      }
      
      public class B extends Activity {
      
          private final Logger logger = LoggerFactory.getLogger(getClass().getSimpleName());
          private ServiceConnection feedConnection;
          private Messenger feedMessenger;
          private A activityA;
      
          @Override
          public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
      
              bindFeed();
          }
      
          private void bindFeed() {
      
              Intent startingIntent = getIntent();
      
              String serviceClassName = startingIntent.getStringExtra(Keys.SERVICE_CLASS_NAME);
      
              Intent intent = new Intent(serviceClassName);
      
              feedConnection = new FeedConnection();
              // FIXME: BIND_AUTO_CREATE flag is missing
              if (!bindService(intent, feedConnection, 0)) {
                  throw new IllegalStateException("Failed to bind to " + serviceClassName);
              }
      
              logger.debug("bindService(" + serviceClassName + ") successful");
          }
      
          private class FeedConnection implements ServiceConnection {
      
              @Override
              public void onServiceConnected(ComponentName className, IBinder service) {
      
                  B.this.feedMessenger = new Messenger(service);
      
                  logger.debug("bound " + className);
      
                  // Finish the previous activity only after the service is bound            
                  activityA.fileList();
              }
      
              @Override
              public void onServiceDisconnected(ComponentName className) {
      
                  B.this.feedMessenger = null;
                  logger.error("Crashed " + className);
              }
          }
      }
      

1 个答案:

答案 0 :(得分:2)

更新:已解决。来自http://developer.android.com/reference/android/app/Service.html

服务既可以启动,也可以绑定连接。在这种情况下,只要系统启动或者使用Context.BIND_AUTO_CREATE标志有一个或多个连接,系统就会保持服务运行。

如果不同的连接处于非对称角色,则不太直观,但唉,就是这样。