重复的远程服务实例

时间:2014-10-13 11:08:03

标签: android sockets service

我有一个奇怪的问题,突然发生在我正在测试我的代码的一些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)。

我希望我已经清楚了。

1 个答案:

答案 0 :(得分:1)

我相信您所看到的是第二个过程,由android:process=":remote"提供,包含您的远程服务,并且您只有一个远程服务实例。

您可以考虑暂时删除android:process=":remote"以暂时运行测试并确认此理论,并永久删除(除非有明确的理由说明您需要消耗更多用户的RAM)。 / p>