2

演習のポイントは、サービスを存続させ、あるアクティビティから別のアクティビティに渡すことです。

  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) を呼び出しています。

予想される動作: サービス S は、アクティビティ B が unbindService() を呼び出すまで問題なく存在し続けます。

実際の動作:

  1. S.onUnbind() が呼び出されます。
  2. S.onDestroy() が呼び出されます。
  3. B.serviceConnection.onServiceDisconnected() が呼び出されます。

したがって、リンクを破壊し、ドキュメントに矛盾します。

なんで?私は何が欠けていますか?

更新: 解決しました。http://developer.android.com/reference/android/app/Service.htmlから:

サービスは、開始することも、接続をバインドすることもできます。このような場合、サービスが開始されているか、 Context.BIND_AUTO_CREATE フラグを使用して1 つ以上の接続が存在する限り、システムはサービスを実行し続けます。

コードは次のとおりです。

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);
        }
    }
}
4

1 に答える 1

2

更新: 解決しました。http://developer.android.com/reference/android/app/Service.htmlから:

サービスは、開始することも、接続をバインドすることもできます。このような場合、サービスが開始されているか、Context.BIND_AUTO_CREATE フラグを使用してサービスへの接続が 1 つ以上ある限り、システムはサービスを実行し続けます。

異なる接続が非対称の役割を果たしている場合は、あまり直感的ではありませんが、残念ながら、それはそれです.

于 2012-05-21T05:20:55.397 に答える