资讯专栏INFORMATION COLUMN

Android Service 之 Bound Services

Travis / 2361人阅读

摘要:适用于和在同一进程内。调用可注意到的,使用以及的使用。此外,客户端也可定义自己的,然后可以发送以便返回结果。但则只是依次处理。但若想同时处理,直接使用。


A bound Service 提供了一种CS模式的Service。
A bound service allows components (such as activities) to bind to the service, send requests, receive responses, and even perform interprocess communication

Server--Extend a Service, 然后实现onBind()方法,返回IBinder对象。
Client--bindService(),然后必须实现ServiceConnection接口,其具有两个方法,onServiceConnected(),可通知连接服务的状态,并返回IBinder对象。
其中onBinder只在第一次服务被连接时才会被调用,之后将直接返回IBinder对象。
当最后一个client unbind时,系统将destroy 该Service.

Creating a Bound Service

继承Binder类
然后将它的一个实例作为onBind()返回值。适用于Server和Client在同一进程内。

创建Server

public class LocalService extends Service {
    // Binder given to clients
    private final IBinder mBinder = new LocalBinder();
    // Random number generator
    private final Random mGenerator = new Random();

    /**
     * Class used for the client Binder.  Because we know this service always
     * runs in the same process as its clients, we don"t need to deal with IPC.
     */
    public class LocalBinder extends Binder {
        LocalService getService() {
            // Return this instance of LocalService so clients can call public methods
            return LocalService.this;
        }
    }

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

    /** method for clients */
    public int getRandomNumber() {
      return mGenerator.nextInt(100);
    }
}
  

Tip: 在LocalBinder中提供了getService()方法,使得客户端可以获得Service的实例,这样就可以调用Service的公共方法。

Client调用:

public class BindingActivity extends Activity {
    LocalService mService;
    boolean mBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to LocalService
        Intent intent = new Intent(this, LocalService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }

    /** Called when a button is clicked (the button in the layout file attaches to
      * this method with the android:onClick attribute) */
    public void onButtonClick(View v) {
        if (mBound) {
            // Call a method from the LocalService.
            // However, if this call were something that might hang, then this request should
            // occur in a separate thread to avoid slowing down the activity performance.
            int num = mService.getRandomNumber();
            Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
        }
    }

    /** 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
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            mBound = true;
        }

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

可注意到Service的bind,使用以及unBind()的使用。

使用Messenger
在Service中Create 一个Handler,然后可以接收和处理不同的Message type,同时Messenger 也可返回一个IBinder对象给客户端。此外,客户端也可定义自己的Messenger,然后Service可以发送Message以便返回结果。最简单的实现IPC通信。适用于跨进程。

public class MessengerService extends Service {
    /** Command to the service to display a message */
    static final int MSG_SAY_HELLO = 1;

    /**
     * Handler of incoming messages from clients.
     */
    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SAY_HELLO:
                    Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    /**
     * Target we publish for clients to send messages to IncomingHandler.
     */
    final Messenger mMessenger = new Messenger(new IncomingHandler());

    /**
     * When binding to the service, we return an interface to our messenger
     * for sending messages to the service.
     */
    @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
        return mMessenger.getBinder();
    }
}

以下是Messenger的定义

  

Reference to a Handler, which others can use to send messages to it. This allows for the implementation of message-based communication across processes, by creating a Messenger pointing to a Handler in one process, and handing that Messenger to another process.

意思是它是对Handler的引用,其他组件可通过它发送消息到handler。允许基于message的handle IPC。它是对Binder的简单包装。

Client 调用

public class ActivityMessenger extends Activity {
    /** Messenger for communicating with the service. */
    Messenger mService = null;

    /** Flag indicating whether we have called bind on the service. */
    boolean mBound;

    /**
     * Class for interacting with the main interface of the service.
     */
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            // This is called when the connection with the service has been
            // established, giving us the object we can use to
            // interact with the service.  We are communicating with the
            // service using a Messenger, so here we get a client-side
            // representation of that from the raw IBinder object.
            mService = new Messenger(service);
            mBound = true;
        }

        public void onServiceDisconnected(ComponentName className) {
            // This is called when the connection with the service has been
            // unexpectedly disconnected -- that is, its process crashed.
            mService = null;
            mBound = false;
        }
    };

    public void sayHello(View v) {
        if (!mBound) return;
        // Create and send a message to the service, using a supported "what" value
        Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
        try {
            mService.send(msg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to the service
        bindService(new Intent(this, MessengerService.class), mConnection,
            Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }
}

就是一个事件传递。

使用AIDL
上个使用Messenger的方式,底层结构也是使用AIDL。但Messenger则只是依次处理。但若想同时处理,直接使用AIDL。适用于跨进程。

  

Tip: 大部分应用无需使用AIDL来创建bound service, 它可能需要多线程处理能力以及更复杂的实现。


  

Caution:Only activities, services, and content providers can bind to a service—you cannot bind to a service from a broadcast receiver.

bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
第三个参数BIND_AUTO_CREATE指create service if its not already alive. 还可以是BIND_DEBUG_UNBIND, BIND_NOT_FOREGROUD, 或者0。

建议:you should bind during onStart() and unbind during onStop().如果希望在App可见时。
若想在activity接收响应在stopped时候,可bind during onCreate() and unbind during onDestroy().

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/12221.html

相关文章

  • Android_Servcie_后台服务总结笔记

    摘要:一个执行单一的任务,不会返回结果给调用者,执行结束后就自行销毁。使用完成后台下载任务的参考链接链接链接源码链接源码链接消息处理机制总结笔记图解和开发什么是版权声明后台服务总结笔记由在年月日写作。 Android通过Activity提供了界面给用户,而App进入后台时用户就不能通过界面操作App了。但某些场景下,用户确实不需要界面,但仍需使用App,比如播放音乐或者获得博文更新的通知。A...

    Jason 评论0 收藏0
  • AndroidService

    摘要:优点默认的处理所有来自收到的请求。依次传递收到到,依次处理。若想得到的返回结果,可用携带一个对象,这样在使用完成后,即可发送发送广播。当不再需要,需要调用进行解绑,使得服务科正常关闭。可使用,但不会停止。 startService(): run indefinetly, 需要在适当时候stopSelf() onBind(): 提供一个CS模式的服务,runs as long as t...

    longmon 评论0 收藏0
  • Android系统开发修改Captive Potal Service(消灭感叹号)

    摘要:谷歌在之后的版本加入了服务。但对于不能访问谷歌服务器的地区,问题就来了如果谷歌谷歌服务认为网络无法联网,就不会自动连接到该热点。并且让网络的标志上面显示感叹号标志。这个感叹号会使广大强迫症晚期患者无法接受。 本文原作者 长鸣鸟 ,未经同意,转载不带名的严重鄙视。谷歌在Android5.0之后的版本加入了CaptivePotalLogin服务。本服务的功能是检查网络连接互联网情况,主要针...

    wenhai.he 评论0 收藏0
  • Android系统开发修改Captive Potal Service(消灭感叹号)

    摘要:谷歌在之后的版本加入了服务。但对于不能访问谷歌服务器的地区,问题就来了如果谷歌谷歌服务认为网络无法联网,就不会自动连接到该热点。并且让网络的标志上面显示感叹号标志。这个感叹号会使广大强迫症晚期患者无法接受。 本文原作者 长鸣鸟 ,未经同意,转载不带名的严重鄙视。谷歌在Android5.0之后的版本加入了CaptivePotalLogin服务。本服务的功能是检查网络连接互联网情况,主要针...

    Zhuxy 评论0 收藏0
  • 关于AndroidService知识点,你知道吗?

    摘要:目录学习相关知识点概述生命周期的基本用法服务。主要是用来后台处理网络事务,播放音乐,执行文件操作和进行交互等。这两种服务各有各的特色。不然会出现主线程被的情况,为应用无反应。用于后台执行用户指定的操作。 目录 学习Service相关知识点: 概述; Service生命周期; Service的基本用法; 服务。 问:达叔,今日工作累吗? 答:累啊,那么问你,你知道Android中的 Se...

    Cobub 评论0 收藏0

发表评论

0条评论

Travis

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<