服务在bindService()之后未被创建(或连接)
我有这个简单的服务,广播用户的当前位置。 我想使用绑定机制来控制服务生命周期,但服务只是没有开始。
我做错了什么?
public class GPSActivity extends ListActivity {
...
protected void onResume() {
super.onResume();
Log.i("Service", "Service bound");
Intent intent = new Intent(this, LocationService.class);
bindService(intent, service_connection , Context.BIND_AUTO_CREATE);
}
protected void onPause() {
if (dataUpdateReceiver!=null)
unregisterReceiver(dataUpdateReceiver);
unbindService(service_connection);
super.onPause();
}
class LocationServiceConnection implements ServiceConnection{
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("Service", "Service Connected");
}
public void onServiceDisconnected(ComponentName name) {
}
}
}
LocalBinder.java
public class LocalBinder<S> extends Binder {
private String TAG = "LocalBinder";
private WeakReference<S> mService;
public LocalBinder(S service){
mService = new WeakReference<S>(service);
}
public S getService() {
return mService.get();
}
}
LocationService.java
public class LocationService extends Service {
public void onCreate() {
initLocationListener();
Log.i("Location Service","onCreate()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("Location Service", "Received start id " + startId + ": " + intent);
return START_NOT_STICKY;
}
private final IBinder mBinder = new LocalBinder<LocationService>(this);
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
AndroidManifest.xml
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
...
<service android:name=".LocationService">
</service>
</application>
编辑:修正了NickT的答案。
清单条目没有意图过滤器或正确的名称
<service
android:enabled="true"
android:name="com.android.gps.services.LocationService">
<intent-filter>
<action android:name="com.android.gps.services.LocationService" />
</intent-filter>
</service>
我用来绑定的意图就像开始一个活动时需要使用的意图一样。 正确的是:
Intent intent = new Intent("com.android.gps.services.LocationService");
onStartCommand只会在服务明确启动时执行,看起来你只是想绑定到它,这很好。 我没有看到你已经正确设置了服务连接。 我发布了我的存根程序,它显示了如何绑定到服务并通过活页夹调用服务中的方法。 您可能会喜欢运行它并查看各种日志消息的顺序。 您显然需要添加您的BroadcastReceiver和onLocationChaged代码以使其对您有用。
活动
package com.servtest.test;
import com.servtest.test.LocationService.LocalBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
public class ServiceTestActivity extends Activity {
boolean mServiceConnected = false;
boolean mBound = false;
private LocationService mLocnServ;
ServiceConnection mServconn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("SVTEST", "Activity service connected");
LocalBinder binder = (LocalBinder) service;
mLocnServ = binder.getService();
// Can't call this methodInTheService UNTIL IT'S BOUND!
mLocnServ.methodInTheService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d("SVTEST", "Activity service disconnected");
mBound = false;
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public void onStart() {
super.onStart();
Log.d("SVTEST", "Activity onStart");
mServiceConnected = bindService(new Intent(
"com.servtest.test.LOCATIONSERVICE"), mServconn,
Context.BIND_AUTO_CREATE);
}
@Override
protected void onResume() {
super.onResume();
Log.d("SVTEST", "Activity onResume");
}
@Override
public void onPause() {
Log.d("SVTEST", "Activity onPause");
super.onPause();
}
@Override
public void onStop() {
Log.d("SVTEST", "Activity onStop");
if (mBound) {
unbindService(mServconn);
mBound = false;
}
super.onStop();
}
}
服务
package com.servtest.test;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
public class LocationService extends Service implements LocationListener {
private final IBinder mBinder = new LocalBinder();
@Override
public void onLocationChanged(Location arg0) {}
@Override
public void onProviderDisabled(String arg0) {}
@Override
public void onProviderEnabled(String arg0) {}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {}
@Override
public IBinder onBind(Intent intent) {
Log.d("SVTEST", "Loc service ONBIND");
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.d("SVTEST", "Loc service ONUNBIND");
return super.onUnbind(intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Won't run unless it's EXPLICITLY STARTED
Log.d("SVTEST", "Loc service ONSTARTCOMMAND");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("SVTEST", "Loc service ONDESTROY");
}
public class LocalBinder extends Binder {
LocationService getService() {
// Return this instance of LocalService so clients can call public methods
return LocationService.this;
}
}
public void methodInTheService() {
// A method you can call in the service
Log.d("SVTEST", "Loc service EXECUTING THE METHOD");
}
}
清单
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.servtest.test"
android:versionCode="1"
android:versionName="1.0" >
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".ServiceTestActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:enabled="true"
android:name="LocationService">
<intent-filter>
<action android:name="com.servtest.test.LOCATIONSERVICE" />
</intent-filter>
</service>
</application>
</manifest>
希望这可以帮助
我有我的Activity
实现ServiceConnection
并像这样绑定:
bindService( new Intent( this, Service.class ), this, Context.BIND_AUTO_CREATE );
然后在我的Activity
处理onServiceConnected()
和onServiceDisconnected()
的回调
当你调用bindService
你可能会得到这个错误:
ActivityManager java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.android.server.am.ActivityRecord$Token
检查logcat的输出。
这是Android的一个错误。
要解决它,请使用getApplicationContext().bindService(...)
上一篇: Service not being created (or connecting) after bindService()