绑定到服务时的Android ClassCast异常

时间:2011-11-07 17:31:43

标签: android binding service android-activity classcastexception

好的,我是android开发的新手,我正在尝试绑定到一个服务,以便我可以在服务启动后调用该服务上的方法。下面描述的Activity和Service都是同一个应用程序的一部分,因此不存在任何问题,但每次运行我的应用程序时都会出现以下错误:

java.lang.ClassCastException:android.os.BinderProxy

这发生的一行是:

LocalBinder binder = (LocalBinder) service;

我的活动代码(简化版):

public class Main extends Activity {

    boolean gpsBound = false;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    /** Called whenever the activity is started. */
    @Override
    protected void onStart() {
        super.onStart();
        // Bind to GPSService
        Intent i = new Intent(this, GPSService.class);
    startService(i);
    bindService(i, connection, Context.BIND_AUTO_CREATE);
    }

    /** service binding */
    private ServiceConnection connection = new ServiceConnection() {

        public void onServiceConnected(ComponentName className, IBinder service) {
            // After binding to GPSService get the instance of it returned by IBinder
        LocalBinder binder = (LocalBinder) service;
            gpsBound = true;
        }

        public void onServiceDisconnected(ComponentName className) {
            gpsBound = false;
        }
    };

}

服务:

public class GPSService extends Service {

    @Override
    public void onCreate() {
            super.onCreate();
    }

    @Override
    public IBinder onBind(Intent i) {
    // TODO Auto-generated method stub
    return new LocalBinder<GPSService>(this);
    }


   /**
    * Our implementation of LocationListener that handles updates given to us
    * by the LocationManager.
    */
    public class CustomLocationListener implements LocationListener {

        DBHelper db;

        CustomLocationListener() {
            super();
        }

    // Overridden methods here...

    }

}

最后是我的LocalBinder:

/**
 * A generic implementation of Binder to be used for local services
 * @author Geoff Bruckner  12th December 2009
 *
 * @param <S> The type of the service being bound
 */

public class LocalBinder<S> extends Binder {
    private String TAG = "LocalGPSBinder";
    private  WeakReference<S> mService;


    public LocalBinder(S service){
        mService = new WeakReference<S>(service);
    }


    public S getService() {
        return mService.get();
    }
}

我理解ClassCast Exception的含义但无法理解该怎么做!我已经按照谷歌文档中的示例,但它仍然无法正常工作。任何人都可以解释可能导致这种情况的原因吗?

提前致谢!

4 个答案:

答案 0 :(得分:32)

删除服务的AndroidManifest.xml中的属性process

答案 1 :(得分:4)

有同样的错误。我在清单中添加了android:process =“:process_description”属性。当你添加它时,你的服务被创建为单独的进程,因此你得到binderProxy的实例(因此类转换异常)

答案 2 :(得分:3)

传入onServiceConnected的LocalBinder有一个泛型类型参数,而你的局部变量LocalBinder binder没有。

通过从LocalBinder的定义中删除泛型类型,或者在onServiceConnected

中添加一个局部变量binder的声明,解决这种或那种方式。
class MyBoundService extends Service{
    private final IBinder mBinder = new MyBinder();

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    public class MyBinder extends Binder{

        public void doStuff(){
            //Stuff
        }
        //More Binder Methods
    }
}

class MyActivity extends Activity{
    private MyBinder mBinder;

    @Override
    protected void onStart(){
        Intent intent = new Intent(this, MyBoundService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop(){
        unbindService(mConnection);
    }

    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            mBinder = (TaskBinder) service;
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBound = false;
        }
    };

    private void doStuff(){
        if (mBound)
            mBinder.doStuff();
    }
}

没有真正需要摆弄弱引用和诸如此类的东西。只是一定要解开(我没有在样本中)

如果要尽快调用服务方法,只需在设置mBinder后将调用放入onServiceConnected。否则,只需从其他回调调用(onClick事件和诸如此类)。

答案 3 :(得分:3)

如果您尝试绑定到本地服务而不是,则可以将其强制转换。但是,如果您尝试绑定到远程(单独进程)服务,则必须使用本文中规定的AIDL方法。

http://developer.android.com/guide/components/aidl.html