绑定到已启动的服务

时间:2014-11-29 05:40:58

标签: 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("onStartCommand","got to onStartCommand");
        return START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.i("onBind", "got to onBind");
        return trackServiceBinder;
    }
}

以下是活动:

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
    }
}

以下是服务的清单:

    <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>

当我在调试器中通过startService()和bindService()逐步运行它时,一切都很好。在Service中,调用onStartCommand(),然后调用onBind(),并使用Binder调用Activity onServiceConnected()。但是,当我没有调试时,由于某种原因,服务在其onStartCommand()方法之前调用 之前的onBind()方法。这是日志的输出:

11-28 23:17:01.805: I/onStart(1103): started TrackService
11-28 23:17:01.815: I/onStart(1103): bound to TrackService
11-28 23:17:01.985: I/onBind(1165): got to onBind
11-28 23:17:01.995: I/onStartCommand(1165): got to onStartCommand

永远不会调用Activity的onServiceConnected()方法。我尝试在bindService()调用中使用BIND_AUTO_CREATE,但没有效果。很明显我在这里遇到某种竞争条件,但是我已经运行了20次,它总是按照相同的顺序运行。我能想到在服务中强制执行正确调用顺序的唯一方法是在Activity中放置一个BroadcastReceiver,并从服务的onStartCommand()方法发送一个Intent,让Activity知道是时候调用bindService( )。这看起来非常糟糕......有没有更好的方法呢?或者是否有一些我错过的导致无序呼叫的东西?

1 个答案:

答案 0 :(得分:0)

您可以拨打startService(),然后等一段时间再拨打bindService()。等待多长时间肯定是一个问题,但我想如果你的Service在启动时没有做大量的工作,那么应该延迟500或1000毫秒。

我会质疑为什么这很重要。 Service有一个onCreate()方法,在Service实例化时调用,无论是先调用onStartCommand()还是onBind()。您应该能够设置您的体系结构,以便在onCreate()中执行所有重要设置,然后调用onStartCommand()onBind()的顺序并不重要。注意:您必须在BIND_AUTO_CREATE

的调用中使用标记bindService()

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