Android uses binder to Access Service (1)

Source: Internet
Author: User

The binder mechanism is the inter-process access mechanism throughout the Android system and is often used to access the service. Let's take a look at how the binder is used to access the service in combination with the code.

You can understand the service as a non-interface activity. It is a program running in the background. The so-called background is relative to the program that can be viewed, and the background program cannot directly interact with each other.

The binder is mainly used for inter-process communication, but can also be used for communication with the local service.

1. Let's first look at an example of communication with the local service.

package com.ckt.wangxin;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.widget.Toast;/** * This is a service stub for both LocalBinderClient * and RemoteBinderClient  * @author Wang Xin * @email springnap@163.com * */public class LocalService extends Service {    @Override    public IBinder onBind(Intent intent) {        return new LocalBinder();    }               public void sayHelloWorld(){        Toast.makeText(this.getApplicationContext(), "Hello World Local Service!", Toast.LENGTH_SHORT).show();    }               public class LocalBinder extends Binder {        LocalService getService() {            // Return this instance of LocalService so clients can call public methods            return LocalService.this;        }       }   }

The Code of local servcie is as follows: The onbinder method returns the binder. The binder contains the Service handle. After the client obtains the handle, it can call the public method of servcie, this call method is the most common.

Client code

package com.ckt.wangxin;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;import com.ckt.wangxin.LocalService.LocalBinder;public class LocalServiceTestActivity extends Activity {    static final String TAG = "LocalBinderTestActivity";    ServiceConnection mSc;        /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                mSc = new ServiceConnection(){            @Override            public void onServiceConnected(ComponentName name, IBinder service) {                Log.d(TAG, "service connected");                LocalService ss = ((LocalBinder)service).getService();                ss.sayHelloWorld();            }            @Override            public void onServiceDisconnected(ComponentName name) {                Log.d(TAG, "service disconnected");            }        };    }        @Override    protected void onStart() {        super.onStart();        Log.d(TAG, this.getApplicationContext().getPackageCodePath());        Intent service = new Intent(this.getApplicationContext(),LocalService.class);        this.bindService(service, mSc, Context.BIND_AUTO_CREATE);    }    @Override    protected void onStop() {        super.onStop();        //must unbind the service otherwise the ServiceConnection will be leaked.        this.unbindService(mSc);    }}

Note that you need to unbind the service in onstop; otherwise, memory leakage may occur.

2. Let's look at the problem of communication with the service in another process (cross-process communication !).

How can I run servcie in another process? Configure attributes in manifest.

Android: Process = ": Remote" indicates that the service runs in different processes of the same application.

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.ckt.wangxin"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk android:minSdkVersion="15" />    <application        android:icon="@drawable/ic_launcher"        android:label="@string/app_name" >        <activity            android:name=".LocalServiceTestActivity"            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>        <!-- android:process=":remote" specify this service run in         another process in the same application. -->        <service android:name=".RemoteService" android:process=":remote"></service>        <activity android:name="RemoteServiceTestActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>                    </activity>    </application></manifest>

The client can use messenger to send messages to the service.

Client code:

package com.ckt.wangxin;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.Handler;import android.os.IBinder;import android.os.Message;import android.os.Messenger;import android.os.RemoteException;import android.util.Log;import android.widget.Toast;public class RemoteServiceTestActivity extends Activity {    static final String TAG = "RemoteServiceTestActivity";    ServiceConnection mSc;    public static final int SAY_HELLO_TO_CLIENT = 0;    /**     * Handler of incoming messages from service.     */    class IncomingHandler extends Handler {        @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case SAY_HELLO_TO_CLIENT:                Toast.makeText(RemoteServiceTestActivity.this.getApplicationContext(), "Hello World Remote Client!",                            Toast.LENGTH_SHORT).show();                    break;                default:                    super.handleMessage(msg);            }        }    }        Messenger messenger_reciever = new Messenger(new IncomingHandler());        /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                mSc = new ServiceConnection(){            @Override            public void onServiceConnected(ComponentName name, IBinder service) {                Log.d(TAG, "service connected");                Messenger messenger = new Messenger(service);                Message msg = new Message();                msg.what = RemoteService.MSG_SAY_HELLO;                msg.replyTo = messenger_reciever;                try {messenger.send(msg);} catch (RemoteException e) {e.printStackTrace();}            }            @Override            public void onServiceDisconnected(ComponentName name) {                Log.d(TAG, "service disconnected");            }        };    }        @Override    protected void onStart() {        super.onStart();        Log.d(TAG, this.getApplicationContext().getPackageCodePath());        Intent service = new Intent(this.getApplicationContext(),RemoteService.class);        this.bindService(service, mSc, Context.BIND_AUTO_CREATE);    }    @Override    protected void onStop() {        super.onStop();        //must unbind the service otherwise the ServiceConnection will be leaked.        this.unbindService(mSc);    }}

Obtain the binder sent from the service, which is used to build a messenger to send messages to the service.

Service Code:

package com.ckt.wangxin;import android.app.Service;import android.content.Intent;import android.os.Handler;import android.os.IBinder;import android.os.Message;import android.os.Messenger;import android.os.RemoteException;import android.widget.Toast;public class RemoteService extends Service {    public static final int MSG_SAY_HELLO = 0;    @Override    public IBinder onBind(Intent intent) {        return messager.getBinder();    }    Handler IncomingHandler = new Handler() {        @Override        public void handleMessage(Message msg) {        if(msg.replyTo != null){        Message msg_client = this.obtainMessage();        msg.what = RemoteServiceTestActivity.SAY_HELLO_TO_CLIENT;        try {((Messenger)msg.replyTo).send(msg_client);} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}        }            switch (msg.what) {                case MSG_SAY_HELLO:                    Toast.makeText(RemoteService.this.getApplicationContext(), "Hello World Remote Service!",                            Toast.LENGTH_SHORT).show();                    break;                default:            super.handleMessage(msg);            }        }    };        Messenger  messager = new Messenger (IncomingHandler);}

Build a messenger, including a handler, and then send the binder of the messenger to the client. The client can construct another messenger to communicate with the service through handler, and the message is processed in the handler.

Currently, the Service side responds to client messages in one way. Likewise, it can send messages in two ways to achieve two-way communication.

The demo source code can be downloaded here.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.