我有一个奇怪的问题,突然发生在我正在测试我的代码的一些Android设备上。
我正在使用由多个活动组成的系统,这些活动共享用于管理整个系统内通信的相同远程服务。
问题是,有时在某些设备上我得到了一个重复的远程服务实例,这可能不是问题,但实际上这是一个大问题。事实上,正如我所说,远程服务用于通过UDP或TCP管理消息交换,当我得到这个服务的多个实例时,我遇到套接字问题,因为两个服务都试图使用相同的端口(广播端口)导致EADDRINUSE异常。
有人可以解释我为什么会得到这个服务的多个实例?
以下是我在我的主要活动中将绑定设置为远程服务的代码,该活动由我的所有活动继承:
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService(new Intent(
MyAction.REMOTE_SERVICE_LOAD));
getApplicationContext().bindService(
new Intent(IRemoteService.class.getName()), mConnection,
Context.BIND_AUTO_CREATE);
}
/** The primary interface we will be calling on the service. */
private IRemoteService mService = null;
private final ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(final ComponentName className,
final IBinder service) {
mService = IRemoteService.Stub.asInterface(service);
try {
mService.registerCallback(mCallback);
launchTask();
} catch (final Throwable e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
try {
if (mConnection != null && mService != null) {
mService.unregisterCallback(mCallback);
getApplicationContext().unbindService(mConnection);
Log.d(tag, "UNREGISTER SERVICE CALLBACK for activity "
+ getClass().getSimpleName());
}
} catch (final Exception e) {
e.printStackTrace();
}
}
//method that will be called when I get a notification on serverUp and i come from
//a serverDown situation
public void notifyConnectionUp() {
if (!serverConnected) {
if (mConnection != null) {
try {
mService.unregisterCallback(mCallback);
} catch (final RemoteException e) {
e.printStackTrace();
}
getApplicationContext().unbindService(mConnection);
}
getApplicationContext().bindService(
new Intent(IRemoteService.class.getName()), mConnection,
Context.BIND_AUTO_CREATE);
System.gc();
}
}
我的远程服务中的代码是:
@Override
public int onStartCommand(final Intent intent, final int flags,
final int startId) {
return START_STICKY;
}
@Override
public IBinder onBind(final Intent intent) {
if (IRemoteService.class.getName().equals(intent.getAction())) {
return mBinder;
}
return null;
}
@Override
public void onCreate() {
Log.d(tag, "onCreate...RemoteService");
//Here I have the registration of some receivers and the launch of other services
}
@Override
public void onDestroy() {
mCallbacks.kill();
}
根据CommonsWare的要求,这是我的服务应用程序上的标记:
<service
android:name="shared.RemoteService"
android:enabled="true"
android:process=":remote">
<intent-filter>
<action
android:name="shared.IRemoteService"/>
<action
android:name="shared.REMOTE_SERVICE"/>
</intent-filter>
</service>
另一个问题是,当我启动一个新活动时,我总是看到对服务的onStartCommand方法的调用吗?我期待调用服务的onBind()方法(考虑到在我的mainActivity中我调用了startService(),然后调用了bindService)。
我看到我有多个远程服务实例,因为当我在设备上运行PS命令时,我得到以下结果:
D / Command(14049):ID:1,u0_a67 14013 2330 478116 28620 ffffffff 40767ce8 R service.net:remote D / Command(14049):ID:1,u0_a67 31493 14013 477100 21416 00000000 40051a58 R service.net:remote
正如您所看到的,似乎一个服务是另一个服务的父服务(第二个服务PPID是14013,这是第一个服务PID)。
我希望我已经清楚了。
答案 0 :(得分:1)
我相信您所看到的是第二个过程,由android:process=":remote"
提供,包含您的远程服务,并且您只有一个远程服务实例。
您可以考虑暂时删除android:process=":remote"
以暂时运行测试并确认此理论,并永久删除(除非有明确的理由说明您需要消耗更多用户的RAM)。 / p>