首页 > 代码库 > Android专题8——本地服务和远程服务通信

Android专题8——本地服务和远程服务通信

关于远程服务

  • 远程服务指的是服务和访问者不在同一个应用程序中,即不在同一个进程中。

  • 访问远程服务类似进程间通信。

  • 访问者和远程服务需要遵守能够被操作系统理解的协议,AIDL。

1. 在服务端和客户端配置AIDL

  • aidl文件最好都放在aidl目录下,aidl文件用于接口描述

  • 会自动生成一个同名的JAVA文件

  • 在自动生成的JAVA文件中,系统会自动定义一个Stub类,继承Binder类,实现aidl文件中描述的接口

技术分享

技术分享

 

2. 编写service业务代码

  • 在清单文件中注册

  • 实现自定义的IBinder

技术分享
        <service android:name=".StudentService">            <intent-filter >                <action android:name="com.njulya.REMOTESERVICE"/>            </intent-filter>        </service>
View Code
技术分享
import com.njulya.aidl.StudentQuery;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;public class StudentService extends Service {    IBinder iBinder;    String[] names = {"张阳","李永安","潘杰"};    @Override    public IBinder onBind(Intent intent) {        iBinder = new StudentBinder();        return iBinder;    }/** * 实现IBinder接口,用于通信 * @author Andy */    private class StudentBinder extends StudentQuery.Stub{        @Override        //aidl文件中描述的接口        public String query(int no) throws RemoteException {            return names[no-1];//业务代码        }            }}
View Code

 

 

3.编写客户端应用

技术分享
package com.njulya.remoteserviceclient;import com.njulya.aidl.StudentQuery;import android.app.Activity;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.view.Menu;import android.view.View;import android.widget.EditText;import android.widget.TextView;public class MainActivity extends Activity {        private EditText studentId;    private TextView content;    private StudentQuery studentQuery;    private ServiceConnection conn;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        studentId = (EditText)this.findViewById(R.id.student_id);        content = (TextView)this.findViewById(R.id.content);        conn = new StudentConnetion();        Intent service = new Intent("com.njulya.REMOTESERVICE");        this.bindService(service, conn, BIND_AUTO_CREATE);    }    /**     * 按键触发业务代码     * @param v     */    public void queryOnClick(View v){        int no = Integer.valueOf(studentId.getText().toString());        try {            String studentName = studentQuery.query(no);            content.setText(studentName);        } catch (RemoteException e) {            e.printStackTrace();        }    }    private class StudentConnetion implements ServiceConnection{        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            //将IBinder代理对象转换为接口类型            studentQuery = StudentQuery.Stub.asInterface(service);        }                @Override        public void onServiceDisconnected(ComponentName name) {            studentQuery = null;        }    }            @Override    protected void onDestroy() {        unbindService(conn);        super.onDestroy();    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.main, menu);        return true;    }    }
View Code

 

关于本地服务

  • 启动的service是运行在主线程中的,所以耗时的操作还是要新建工作线程

  • 用bindService时需要实现ServiceConnection,flags用BIND_AUTO_CREATE

  • service中关键要返回IBinder的实现类对象,该对象中会使用服务中的一些API

  • 一般在自定义的ServiceConnection实现类中得到和关闭IBinder对象

  • 通过得到的IBinder对象实现调用服务中的API

业务界面

技术分享

客户端代码

技术分享
package com.njulya.intsum;import android.os.Bundle;import android.os.IBinder;import android.app.Activity;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;public class MainActivity extends Activity {    private EditText num1;    private EditText num2;    private TextView sum;    private ServiceConnection conn;        //自定义的公共接口,用于求两数之和    private SumOfTwo sumOfTwo;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        num1 = (EditText)this.findViewById(R.id.num1);        num2 = (EditText)this.findViewById(R.id.num2);        sum = (TextView)this.findViewById(R.id.sum);        Button button = (Button)this.findViewById(R.id.button);        button.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                sum();            }        });        conn = new SumConnetion();        Intent service = new Intent(this, SumService.class);        this.bindService(service, conn, BIND_AUTO_CREATE);    }    protected void sum() {        int number1 = Integer.valueOf(num1.getText().toString());        int number2 = Integer.valueOf(num2.getText().toString());        int result = sumOfTwo.sum(number1, number2);        sum.setText(String.valueOf(result));            }    private class SumConnetion implements ServiceConnection{        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            sumOfTwo = (SumOfTwo)service;        }        @Override        public void onServiceDisconnected(ComponentName name) {            sumOfTwo = null;        }    }        @Override    protected void onDestroy() {        unbindService(conn);        super.onDestroy();    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.main, menu);        return true;    }}
View Code

服务端代码

技术分享
package com.njulya.intsum;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;public class SumService extends Service {    @Override    public IBinder onBind(Intent intent) {        // TODO Auto-generated method stub        return new SumBinder();    }    public class SumBinder extends Binder implements SumOfTwo{        @Override        public int sum(int number1, int number2) {            return number1 + number2;        }            }}
View Code

 

Android专题8——本地服务和远程服务通信