代码之家  ›  专栏  ›  技术社区  ›  JoaoFilipeClementeMartins

每个服务绑定是否需要有一个ServiceConnection?

  •  6
  • JoaoFilipeClementeMartins  · 技术社区  · 12 年前

    我有几个Android Service 我想在我的 Activity ,因此我可以监视用户的几个操作。

    为了能够绑定每个服务,我将有几个,我需要几个私人服务吗 ServiceConnection 我的活动如下?

    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {
    
        @Override
        public void onServiceConnected(ComponentName className,
                IBinder service) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            GPSLocalBinder gpsBinder = (GPSLocalBinder) service;
            PhotoLocalBinder photoBinder = (PhotoLocalBinder) service;
            gpsService = gpsBinder.getService();
            photoService = photoBinder.getService();
            mGpsBound = true;
            mPhotoBound = true;
        }
    
        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mGpsBound = false;
            mPhotoBound = false;
        }
    };
    

    或者,我的活动和服务之间是否需要一个管理器类,以便更好地使用和理解有界的服务?

    2 回复  |  直到 9 年前
        1
  •  1
  •   Merlevede    12 年前

    每个android是否需要一个serviceConnection 服务

    我想你是在问是否可以重复使用 serviceConnection 用于多种服务。不需要为每个服务连接设置一个,但这可能是最好的方法。我在你的代码中看到

            GPSLocalBinder gpsBinder = (GPSLocalBinder) service;
            PhotoLocalBinder photoBinder = (PhotoLocalBinder) service;
            gpsService = gpsBinder.getService();
            photoService = photoBinder.getService();
    

    这很令人困惑。。。这似乎可以将一个服务转换为两个不同的服务!!

    你会意识到 onServiceConnected 回调是最神奇的地方,在这里您(活动)最终可以获得指向服务的指针,并开始调用方法并与服务交互。如果您想重复使用相同的 服务连接 对于不同的服务,您需要找出IBinder对象属于哪个自定义子类,然后进行适当的转换。乌夫,麻烦太多了。我建议喝一杯 服务连接 每个服务。

    或者我需要在我的活动和 提供更好的使用和理解有界服务?

    对于这个问题和第一个问题,你可以做任何你想做的事。没有比其他方法更好的方法(IMHO),最好的方法是你更了解并让你感觉更舒适的方法。

        2
  •  0
  •   Sufian    9 年前

    一张单曲 ServiceConnection 实例可用于绑定到多个服务。

    在里面 ServiceConnection.onServiceConnected() ,您必须检查绑定了哪个服务(使用 className.getClassName() className.getPackageName() )并将其放入适当的字段/变量等。

    我用过 this thread 作为参考,尽管我修改了它以满足我的需求。

    private static final int SERVICE_1_INDEX = 0;
    private static final int SERVICE_2_INDEX = 1;
    
    /** Array of the subclasses of {@link BaseService}s which have been bound */
    private BaseService[] mServices;
    /** ServiceConnection which handles the binding/unbinding of the services */
    private MyServiceConnection mServiceConnection;
    
    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mServiceConnection = new MyServiceConnection();
    }
    
    @Override
    public void onResume() {
        super.onResume();
        bindServices();
    }
    
    @Override
    public void onPause() {
        super.onPause();
        unbindServices();
    }
    
    private void bindServices() {
        Intent service1Intent = new Intent(getActivity().getApplicationContext(), MyService1.class);
        Intent service2Intent = new Intent(getActivity().getApplicationContext(), MyService2.class);
    
        getContext().bindService(service1Intent, mServiceConnection, Context.BIND_AUTO_CREATE);
        getContext().bindService(service2Intent, mServiceConnection, Context.BIND_AUTO_CREATE);
    }
    
    private void unbindServices() {
        if (mServiceConnection != null) {
            getContext().unbindService(mServiceConnection);
        }
    }
    
    private class MyServiceConnection implements ServiceConnection {
        public void onServiceConnected(ComponentName className, IBinder boundService ) {
            Log.d("className(bound)", className.getClassName());
            Log.d("className(Service1)", MyService1.class.getName());
            Log.d("className(Service2)", MyService2.class.getName());
            BaseService.LocalBinder binder = (BaseService.LocalBinder) boundService;
            if (className.getClassName().equals(MyService1.class.getName())) {
                mServices[SERVICE_1_INDEX] = binder.getService();
                // call method on your service like:
                // binder.getService().someMethod();
                // (you may need to cast to your actual Service)
            }
            else {
                mBaseServices[SERVICE_2_INDEX] = binder.getService();
                // call method on the service like in if-block
            }
        }
    
        public void onServiceDisconnected(ComponentName className) {
            if (className.getClassName().equals(MyService1.class.getName())) {
                mBaseServices[SERVICE_1_INDEX] = null;
            }
            else {
                mBaseServices[SERVICE_2_INDEX] = null;
            }
        }
    }