【问题标题】:Android Service can be bind without start?Android服务可以绑定不启动?
【发布时间】:2011-04-28 13:27:28
【问题描述】:

到目前为止,在许多文章、教程、文档中,我们调用 startService() 或 bindService() 都会启动服务。我们也可以同时调用两者,但这是一个不同的故事。如果没有 startService(),我将无法绑定服务。

    private void bindTunManagerService(int flags) {
    TunnelManagerService.setParentActivity(this);
    Intent bindIntent = new Intent(this, TunnelManagerService.class);
    startService(bindIntent);
    tunManagerServiceStarted = bindService(bindIntent, tunConnection, BIND_AUTO_CREATE);

    Log.d(TAG, "tunManagerServiceStarted  : " + tunManagerServiceStarted + ", ** tunManagerService = " + tunManagerService );

在上面的代码中,如果我注释 startService(),bindService 返回 false 并且 tunManagerService = null,即使 onServiceConnected 也没有启动,我得到“Unable to sart service intent {...} not found”消息。添加startService后,调用service的onCreate、onStart、onServiceConnected,绑定成功。

在实际使用中,是否需要先startServie & 然后才能bindService()。这意味着没有 startSERve,我们无法绑定服务!如果这句话是错误的,为什么我不启动它就无法绑定服务?

有什么想法吗????

添加代码

服务连接:

    private ServiceConnection tunConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        Log.d(TAG,"onServiceConnected" );
        tunManagerService = ITunnelManagerService.Stub.asInterface(service);
        doConnect();
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        Log.d(TAG,"onServiceDisconnected" );
        tunManagerService = null;
    }

};

服务:

public class TunnelManagerService extends Service {
@Override
public IBinder onBind(Intent arg0) {
    return binder;
}

@Override
public void onCreate() {
    super.onCreate();
    Log.d(TAG, "TunnelManagerService: onCreate");
    setCreatedPreference(true);
    notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.i(TAG, "Received start id " + startId + ": " + intent);
    return START_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();
    setCreatedPreference(false);
    hideNotifConnected();
    Log.d(TAG, "TunnelManagerService: onDestroy");
}

private final ITunnelManagerService.Stub binder = new ITunnelManagerService.Stub() {
  // contains all methods
}

...............
.............

}

清单:

        <activity android:name=".StartUltimate" android:label="@string/app_name" 
         android:launchMode="singleTask" android:windowSoftInputMode="stateHidden|adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service android:name="orange.android.vpn.utilities.TunnelManagerService" android:enabled="true"></service>

我使用 2.3.3 SDK 即 API 10。我从中调用的活动位于“orange.android.vpn”中,服务相关文件分别位于“orange.android.vpn.utilities”包中。

【问题讨论】:

  • 你使用什么api级别?在 2.1 上,我让这种行为正常工作。
  • 请发布您的服务和您的 ServiceConnection 的代码。另外,你看过 logcat 的输出了吗?它是否显示任何错误?如果是这样,也将其发布在这里。
  • @Jake,不,我找不到那个帖子的副本。
  • 已添加服务和服务连接代码。在 logcat 中,我只收到“无法启动服务 Intent {....} not found ActivityManager 警告。没有其他异常或错误。

标签: android android-service


【解决方案1】:

我找到了解决办法,所以分享给大家。

有两种类型的服务:一种是您启动和停止的。这只能在应用程序中启动和停止一次。 其他您根据需要绑定和取消绑定 N 次。 我的服务属于第二种类型。但只是绑定和解除绑定并不能完成这项工作。服务首先需要启动,然后才可以绑定和取消绑定。因此,在启动应用程序或任何适当的地方,启动服务。然后在需要时绑定。当不使用它时,解开它。绑定-解除绑定循环可以继续。最后,当您确定不需要它或在应用程序结束时停止服务。所以流量来了 开始 -> 绑定 -> 解除绑定 -> 停止

希望这对某人有所帮助。

【讨论】:

  • bindService() 如果服务还没有启动,它实际上会启动它。
  • @Jason:是的,但是一些关键的事情可能会在服务中的 onStartCommand 中完成。我现在正在使用一项服务,事实证明只有明确启动该服务才能工作。这也是对 Tvd 解决方案的解释。
  • 这似乎不是答案。您应该能够绑定到服务而无需显式启动它。如果您还想在绑定时启动它: bing 服务并将标志 Context.BIND_AUTO_CREATE 传递给它
  • 引用当一个服务与所有客户端解除绑定时,Android系统会销毁它(除非它也是用onStartCommand()启动的)developer.android.com/guide/components/…
  • 这是一个误导性的答案。只需调用 bindService 并传递 BIND_AUTO_CREATE 标志即可启动服务。由于您的回答,我认为服务始终需要在绑定之前启动。但是后来我为自己尝试了它,我能够在不显式调用 startService() 的情况下这样做。请修改您的答案,以免误导其他人。
【解决方案2】:

是的。

bindService(new Intent(this, MyService.class), mConnection, 0);

AFAIK,这将始终返回 true(假设 MyService 没有问题)

有两种情况:

  1. 该服务之前已启动 - 调用了 mConnection 的 onServiceConnected()
  2. 该服务之前没有启动过 - 没有调用 mConnection 的 onServiceConnected() 并且该服务没有启动。但是,一旦服务启动(通过其他方式),就会调用 onServiceConnected()

实际上,当我调用此方法时,我假设在调用 onServiceConnected() 方法之前服务不会启动。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    相关资源
    最近更新 更多