绑定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
似乎是个好方法。
检查您是否已绑定到 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
似乎是个好方法。