2.App Components-Services/Bound Services

1. Bound Services

  A bound service is the server in a client-server interface. A bound service allows components (such as activities) to bind to the service, send

    requests, receive responses, and even perform interprocess communication (IPC). A bound service typically lives only while it serves

    another application component and does not run in the background indefinitely

 

2. The Basics

  A bound service is an implementation of the Services class that allows other applications to bind to it and interact with it. To provide binding

    for a service, you must implement the onBind() callback method. This method returns an IBinder object that defines the programming

    interface that clients can use to interact with the service.

3. Creating a Bound Service

  When creating a service that provides binding, you must provide an IBinder that provides the programming interface that clients can use to

    interact with the service. There are three ways you can define the interface:

    <1>Extending the Binder class

    <2>Using a Messenger

    <3>Using AIDL

 

4. Extending the Binder class

  If your service is private to your own application and runs in the same process as the client (which is common), you should create your

    interface by extending the Binder class and returning an instance of it from onBind(). The client receives the Binder and can use it to

    directly access public methods available in either the Binder implementation or even the Service.

  This is the preferred technique when your service is merely a background worker for your own application. The only reason you would not

    create your interface this way is because your service is used by other applications or across separate processes.

//activity_bingding.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="mirror.android.extendingbinder.BindingActivity" >
    <Button
        android:id = "@+id/btn_create_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Create service" />
</RelativeLayout>
//LocalService.class
package mirror.android.extendingbinder;

import java.util.Random;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

public class LocalService extends Service {    
    
    private final IBinder mBinder = new LocalBinder();
    private final Random mGenerator = new Random();
    
    /*1.In your service, create an instance of Binder that either: 
     *     <1> contains public methods that the client can call
     *  <2> returns the current Service instance, which has public methods the client can call
     *  <3> or, returns an instance of another class hosted by the service with public methods the client can call
    */
    public class LocalBinder extends Binder{
        LocalService getService(){
            return LocalService.this;
        }
    }
     
    /*2.Return this instance of Binder from the onBind() callback method.
    */
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return mBinder;
    }
    
    /*The LocalBinder provides the getService() method for clients to retrieve the current instance of LocalService. 
     *This allows clients to call public methods in the service. 
     *For example, clients can call getRandomNumber() from the service.*/
    public int getRandomNumber(){
        return mGenerator.nextInt();
    }
}
//BindingActivity.class
package mirror.android.extendingbinder;

import mirror.android.extendingbinder.LocalService.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.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;


public class BindingActivity extends Activity {
    
    private Button button;
    
    LocalService mService;
    Boolean mBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_binding);
        
        button = (Button)findViewById(R.id.btn_create_service);
        ButtonListener buttonListener = new ButtonListener();
        button.setOnClickListener(buttonListener);
    }

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

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onStop() {
        super.onStop();
        //2.unbind from service
        if(mBound){
            unbindService(mConnection);
            mBound = false;
        }
    }
    
    class ButtonListener implements OnClickListener{
        //3.Call a method from the LocalService.
        //create a separate thread if needed;
        @Override
        public void onClick(View v) {
            if(mBound){
                int num = mService.getRandomNumber();
                Toast.makeText(getApplicationContext(), "number: " + num, Toast.LENGTH_SHORT).show();
            }
        }
    }
    
    private ServiceConnection mConnection = new ServiceConnection() {
        //3.In the client, receive the Binder from the onServiceConnected() callback method 
        //  and make calls to the bound service using the methods provided.
        @Override
        public void onServiceDisconnected(ComponentName name) {
            mBound = false;
        }
        
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            LocalBinder binder = (LocalBinder)service;
            mService = binder.getService();
            mBound = true;
        }
    };
}
//manifest.xml
<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".BindingActivity"
            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:name=".LocalService"></service>
    </application>

  

5. Using a Messenger

  If you need your service to communicate with remote processes, then you can use a Messenger to provide the interface for your service.

    This technique allows you to perform interprocess communication (IPC) without the need to use AIDL.

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。