Android 绑定到已启动的服务

Android 绑定到已启动的服务,android,android-intent,android-service,android-service-binding,Android,Android Intent,Android Service,Android Service Binding,我有一个远程服务,从startService()开始,然后用bindService()绑定。我这样做是因为我希望服务在后台运行,直到应用程序显式停止它,即使用户用刷卡关闭活动。以下是服务的相关部分: public class TrackService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("onSta

我有一个远程服务,从startService()开始,然后用bindService()绑定。我这样做是因为我希望服务在后台运行,直到应用程序显式停止它,即使用户用刷卡关闭活动。以下是服务的相关部分:

public class TrackService extends Service {

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("onStartCommand","got to onStartCommand");
        return START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.i("onBind", "got to onBind");
        return trackServiceBinder;
    }
}
    <service
        android:name=".TrackService"
        android:process=":track_service_process"
        android:stopWithTask="false"
        android:label="@string/track_service_label"
        android:exported="false"
        android:enabled="true">
        <intent-filter>
            <action android:name="com.mydomain.gpslogger.TrackService" />
        </intent-filter>
    </service>
活动内容如下:

public class GPSLoggerActivity extends Activity implements ServiceConnection {

    @Override
    protected void onStart() {
        super.onStart();

        Intent intent = new Intent(TrackService.class.getName());
        intent.setClass(getApplicationContext(), TrackService.class);

        startService(intent);
        Log.i("onStart", "started TrackService");

        if (!getApplicationContext().bindService(intent, this, 0)) {
            // close the Activity
        }

        Log.i("onStart", "bound to TrackService");
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        Log.i("onServiceConnected", "got here");

        // get and use the interface from the Binder
    }
}
以下是该服务的清单:

public class TrackService extends Service {

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("onStartCommand","got to onStartCommand");
        return START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.i("onBind", "got to onBind");
        return trackServiceBinder;
    }
}
    <service
        android:name=".TrackService"
        android:process=":track_service_process"
        android:stopWithTask="false"
        android:label="@string/track_service_label"
        android:exported="false"
        android:enabled="true">
        <intent-filter>
            <action android:name="com.mydomain.gpslogger.TrackService" />
        </intent-filter>
    </service>

永远不会调用活动的OnServiceConnectiond()方法。我尝试在bindService()调用中使用BIND\u AUTO\u CREATE,但没有效果。很明显,我在这里有一些比赛条件,但我已经跑了大概20次了,而且总是以相同的顺序出现。我能想到的在服务中强制执行正确调用顺序的唯一方法是在活动中放置一个BroadcastReceiver,并从服务的onStartCommand()方法发送一个意图,让活动知道该调用bindService()了。这看起来很麻烦…有更好的方法吗?或者是我遗漏了什么导致了无序调用?

您可以调用
startService()
,然后等待一段时间再调用
bindService()
。等待多长时间当然是个问题,但我认为如果您的
服务启动时没有做大量的工作,500或1000毫秒的延迟应该可以完成

我想问为什么这很重要。
Service
有一个
onCreate()
方法,在实例化
Service
时调用该方法,而不管是先调用
onstart命令()
还是
onBind()
。您应该能够设置您的体系结构,以便在
onCreate()
中执行所有重要的设置,然后调用
onStartCommand()
onBind()
的顺序应该无关紧要。注意:在调用
bindService()


我也不明白为什么没有调用
onServiceConnected()
方法。除非对
bindService()
的调用返回
false
(这基本上意味着Android找不到要绑定的
服务),否则您应该得到
onServiceConnected()
回调。这听起来很奇怪。一种可能是
服务
onCreate()
中崩溃,或者执行
onCreate()
方法花费的时间太长,在这种情况下,Android将声明
服务
已损坏。

您的服务正在运行到另一个进程中……您是否尝试过使用Android:exported=“true”?不会影响它。我认为导出属性允许其他应用程序查看该服务。。。尽管这是一个不同的过程,但它是同一个应用程序。我实现了我在问题中提出的乱七八糟的解决方案,而且效果很好。似乎仍然应该有一个更优雅的解决方案