【问题标题】:Binding to a started Service绑定到已启动的服务
【发布时间】:2014-11-29 05:40:57
【问题描述】:

我有一个远程服务,我从 startService() 开始,然后使用 bindService() 绑定。我这样做是因为我希望服务在后台运行,直到应用程序明确停止它,即使用户通过滑动关闭 Activity 也是如此。以下是服务的相关部分:

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(),而在 Activity 中,onServiceConnected() 被 Binder 调用。但是,当我不调试时,由于某种原因,服务会在 其 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 次,而且它总是以相同的顺序出现。我能想到的在 Service 中强制执行正确调用顺序的唯一方法是将 BroadcastReceiver 放入 Activity 并从 Service 的 onStartCommand() 方法发送 Intent 以让 Activity 知道是时候调用 bindService( )。这看起来很笨拙......有没有更好的方法来做到这一点?还是有什么我遗漏的东西导致了无序调用?

【问题讨论】:

  • 您的服务正在运行到不同的进程...您是否尝试过使用 android:exported="true"?
  • 不影响它。我认为导出的属性允许其他应用程序看到该服务......即使这是一个不同的过程,它也是同一个应用程序。我实施了我在问题中提出的kludge修复并且它有效。似乎仍然应该有一个更优雅的解决方案

标签: android android-intent android-service android-service-binding


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 2012-03-04
    相关资源
    最近更新 更多