绑定Android服务

Binding Android service

检查您是否已绑定到 Android 中的服务的常用方法是在绑定步骤中保留一个布尔参数,例如 mBound,如 Android 开发人员指南中所述。我注意到这个 Android 参考教程中的一个问题,我认为这种方法在某种程度上是一种不好的做法。这是来自 Bound Services:

的代码

这里是一个代码块,以语言代码作为提示:

public class ActivityMessenger extends Activity {
    Messenger mService = null;
    boolean mBound;

    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            mService = new Messenger(service);
            mBound = true;
        }

        public void onServiceDisconnected(ComponentName className) {
            mService = null;
            mBound = false;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to the service
        bindService(new Intent(this, MessengerService.class), mConnection,
            Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }
}

好的,问题来了。让我们假设出于任何原因 OnStop()OnStart() 之后立即被调用。您可以通过在 OnCreate() 中放置断点并等待 phone 屏幕变暗强制应用程序重新创建然后继续应用程序来创建这种情况 运行.

如果出现这种情况,当你运行OnStop()时,mBount变量仍然是false,因为服务连接的onServiceConnected()还没有被调用.因此,您不会调用 unbindService(),并且您将拥有一个已绑定且从未解除绑定的服务。

对于绑定服务的更好方法有什么建议吗?我想知道在任何情况下调用 unbideService() 是否足够(例如即使服务现在未绑定也调用)。

此致

我没有在实践中尝试过,但是在 调用 bindService 时设置 mBound = true 似乎是合理的,而不是在回调中。实际上,documentation 表示即使 bindService 返回了 false,你也应该调用 unbindService(这意味着你永远不会得到任何 onServiceConnected 调用和 mBound永远不会是真的):

Note: If the method returns false, your client does not have a valid connection to the service. However, your client should still call unbindService(); otherwise, your client will keep the service from shutting down when it is idle.

考虑到这一点,显然仅在 onServiceConnected 中设置 mBound = true 是不够的(或至少是推荐的)。我怀疑在之前未绑定时调用 unbindService 是 no-op,但这可能需要一些确认。如果是这样,在调用 bindService 时设置 mBound = true 似乎是个好方法。