多语言展示
当前在线:1633今日阅读:23今日分享:31

Android studio 使用aidl实现远程服务

以前在eclipse上开发Android项目习惯了,突然转到Android studio上总是会有这样那样的不适应。例如使用aidl实现远程服务,也就是RPC机制,在Android studio上的开发与在eclipse上的开发便有诸多不同。如果将服务与客户端放在一个项目中还好处理,不同项目中却是增加不少难度。尤其是Android5.0以后服务禁止隐式启动,很多人就非常不习惯。此处就简单介绍一下在Android studio上的aidl创建远程服务的例子(包括Android4.4和Android5.1的开发)。
工具/原料

Android studio

方法/步骤
1

新建项目aidl,在aidl中创建aidl文件IMyService.aidl,具体创建过程可以参考http://jingyan.baidu.com/article/6f2f55a15d53c9b5b93e6ca1.html。在aidl文件中声明方法int add(int value1, int value2);具体代码如下:// IMyService.aidlpackage com.example.aidl;// Declare any non-default types here with import statementsinterface IMyService {    /**     * Demonstrates some basic types that you can use as parameters     * and return values in AIDL.     */     //  为AIDL服务的接口方法,调用AIDL服务的程序需要调用该方法    int add(int value1, int value2);}

2

编译后会自动生成一个对应的Java文件ImyService,至于这个aidl文件在哪儿呢?就像很多人在Android studio中找不到R文件,他们可以这样查找:点击左上角Packages,找到项目名点开即可。

3

创建MyService类,提供服务。服务中的onBind方法要返回实现了IMyService方法的一个类,例如此处使用类MyServiceImpl实现aidl接口中的add方法。代码如下:   class MyServiceImpl extends IMyService.Stub{    @Override    public int add(int value1, int value2) throws RemoteException {        return value1 +value2;    }}整个服务的代码是:package com.example.aidl;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.support.annotation.Nullable;/** * Created by Administrator on 2015/8/12. */public class MyService extends Service {//    @Nullable    //实现接口中的方法    class MyServiceImpl extends IMyService.Stub{    @Override    public int add(int value1, int value2) throws RemoteException {        return value1 +value2;    }}    //返回方法实现类    @Override    public IBinder onBind(Intent intent) {        return new MyServiceImpl();    }}

4

然后在Activity中启动该服务就行。注意,Android5.0以后服务不能隐式启动,必须显示启动,不然会报错。package com.example.aidl;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Intent intent = new Intent();        intent.setAction('com.android.MYSERVICE');        //Android5.0后service不能采用隐式启动,故此处加上包名        intent.setPackage('com.example.aidl');//        Intent intent = new Intent('com.android.MYSERVICE');        startService(intent);        Log.e('MainActivity', 'server start');    }}

5

最后,在Manifest中声明该服务:                        

6

运行该项目,就可以看到控制台打印了server start,至此,服务端就算ok了。

7

新建项目aidlclient作为客户端,创建一个aidl文件并复制服务端aidl文件的内容(或者直接将服务端aidl文件拷过来),注意包名要一致。在布局文件中设置了一个textview和两个button。首先实现服务的连接和断开:IMyService iMyService;//实现服务连接private ServiceConnection mConn = new ServiceConnection() {    @Override    public void onServiceConnected(ComponentName name, IBinder service) {        Log.e('MainActivity','connect service start');        iMyService = IMyService.Stub.asInterface(service);        Log.e('MainActivity','connect service');    }    @Override    public void onServiceDisconnected(ComponentName name) {        Log.e('MainActivity','disconnect service');        iMyService = null;    }};然后点击button1连接服务:Intent intent = new Intent();intent.setAction('com.android.MYSERVICE');//Android5.0后service不能采用隐式启动,故此处加上包名//此处包名与aidl文件包名一致intent.setPackage('com.example.aidl');bindService(intent, mConn, Context.BIND_AUTO_CREATE);最后调用服务的方法即可:try {    i = iMyService.add(2, 3);} catch (RemoteException e) {    e.printStackTrace();}具体代码如下:package com.example.aidlclient;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.IBinder;import android.os.RemoteException;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.Button;import android.widget.TextView;import com.example.aidl.IMyService;public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(com.example.aidlclient.R.layout.activity_main);        final TextView textView = (TextView)findViewById(R.id.text);        Button button1 = (Button)findViewById(R.id.button1);        Button button2 = (Button)findViewById(R.id.button2);        button1.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {//                Intent intent = new Intent('com.android.MYSERVICE');                Intent intent = new Intent();                intent.setAction('com.android.MYSERVICE');                //Android5.0后service不能采用隐式启动,故此处加上包名                //此处包名与aidl文件包名一致                intent.setPackage('com.example.aidl');                bindService(intent, mConn, Context.BIND_AUTO_CREATE);            }        });        button2.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                int i = 0;                try {                    i = iMyService.add(2, 3);                } catch (RemoteException e) {                    e.printStackTrace();                }//                textView.setText(i);                Log.e('MainActivity',i +'>>>>>>>>>>');            }        });    }    IMyService iMyService;    //实现服务连接    private ServiceConnection mConn = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            Log.e('MainActivity','connect service start');            iMyService = IMyService.Stub.asInterface(service);            Log.e('MainActivity','connect service');        }        @Override        public void onServiceDisconnected(ComponentName name) {            Log.e('MainActivity','disconnect service');            iMyService = null;        }    };}

8

顺便贴出客户端布局文件:        

9

最后贴出服务端和客户端的结构图:

推荐信息