美文网首页
Service AIDL简单使用

Service AIDL简单使用

作者: 萝卜小青菜丶 | 来源:发表于2019-11-13 11:06 被阅读0次

AIDL(Android Interface Definition Language)是Android接口定义语言的意思,它可以用于让某个Service与多个应用程序组件之间进行跨进程通信,从而可以实现多个应用程序共享同一个Service的功能。实际上实现跨进程之间通信的有很多,
比如广播,Content Provider,但是AIDL的优势在于速度快(系统底层直接是共享内存),性能稳,效率高,一般进程间通信就用它。
既然是跨进程,那必须的有两个应用,一个是service端,一个是client端,然后实现客户端从服务端获取数据。那么我们创建一个服务端,项目结构如图所示:


服务端

在服务端下建立一个MyAIDLService.aidl文件,目录结构为如图所示:


image.png

然后,在MyAIDLService下增加一个获取字符串的方法。代码如下:

// MyAIDLService.aidl
package aidl;

// Declare any non-default types here with import statements

interface MyAIDLService {
//获取String数据
String getString();
}

创建完aidl文件以后,我们build一下项目,然后会在build - >generated ->source ->aidl->debug下会生成一个aidl文件,那说明AIDL文件已经编译成功。
接着建立一个MyService类,代码如下:

package com.example.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import java.util.Map;

import aidl.MyAIDLService;

public class MyService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
    }

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

    class Mybind extends MyAIDLService.Stub {

        @Override
        public String getString() throws RemoteException {
            String string = "我是从服务起返回的";

            return string;
        }
    }
}

继承的是MyAIDLService.Stub,是刚刚建立的aidl文件,然后实现我们刚刚的定义的
getString()方法,在这里,我们只是返回一句话,"我是从服务起返回的"

客户端

首先将刚刚在服务端创建的MyAIDLService原封不动的复制到客户端来。(注意:路径要一模一样)。接着我们在客户端的MainActivity中加两个按钮,并且和服务端进行相连,代码如下:

package com.example.administrator.servicetestaidl;

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.View;
import android.widget.Button;
import android.widget.TextView;

import aidl.MyAIDLService;

public class MainActivity extends Activity {

    private Button bindService,unbindService;
    private TextView tvData;
    private MyAIDLService myAIDLService;


    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myAIDLService = MyAIDLService.Stub.asInterface(service);
            try {
                String str =  myAIDLService.getString();
                tvData.setText(str);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            myAIDLService = null;
        }
    };




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

        bindService = (Button) findViewById(R.id.bind_service);
        unbindService = (Button) findViewById(R.id.unbind_service);
        tvData = (TextView) findViewById(R.id.tv_data);


        /**
         * 绑定服务
         */
        bindService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setAction("com.example.service.MyService");
                //从 Android 5.0开始 隐式Intent绑定服务的方式已不能使用,所以这里需要设置Service所在服务端的包名
                intent.setPackage("com.example.service");
                bindService(intent, connection, BIND_AUTO_CREATE);



            }
        });

        /**
         * 解绑服务
         */
        unbindService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                unbindService(connection);
            }
        });
    }
}

这里只需要注意两个地方,一个是绑定服务的时候,因为从 Android 5.0开始 隐式Intent绑定服务的方式已不能使用,所以这里需要设置Service所在服务端的包名

那么这个action是怎么来的呢,我们回来服务端的AndroidManifest.xml,代码如下

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.service">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".MyService"
           >
            <intent-filter>
                <action android:name="com.example.service.MyService" />
            </intent-filter>

        </service>
    </application>

</manifest>

另一个需要注意的就是获取MyAIDLService对象是通过MyAIDLService.Stub.asInterface(service);这里需要注意一下的。
不过还有一点需要说明的是,由于这是在不同的进程之间传递数据,Android对这类数据的格式支持是非常有限的,
基本上只能传递Java的基本数据类型、字符串、List或Map等。那么如果我想传递一个自定义的类该怎么办呢?这就必须要让这个类去实现Parcelable接口,
并且要给这个类也定义一个同名的AIDL文件。这部分内容并不复杂,而且和Service关系不大,所以就不再详细进行讲解了,感兴趣的朋友可以自己去查阅一下相关的资料。

注意:从服务器复制过来的aidl文件不能直接放到Java文件夹下面,必须建立一个aidl文件夹存放,否则会编译不成功

相关文章

  • Service AIDL简单使用

    AIDL(Android Interface Definition Language)是Android接口定义语言...

  • 进程间通信之AIDL解析

    在前面《Activity与Service数据交互的几种方式》文章中,讲解了AIDL是什么,AIDL的使用流程,AI...

  • 2019-02-13 AIDL 在 studio 中简单使用

    通过使用AIDL在两个应用间实现通信 一、创建 service 端 新建一个 service project 在对...

  • Binder 连接池

    典型的AIDL使用流程:首先创建一个Service和一个AIDL接口,接着创建一个类继承自AIDL接口中的Stub...

  • IPC机制之Binder连接池

    AIDL典型的使用流程 首先是创建一个Service和一个AIDL接口,接着创建一个类继承自AIDL接口中的Stu...

  • AIDL 跨进程调用 -- 接口层解析

    基本使用方式 Service 和 Client 都需要声明一模一样的aidl 文件, 然后Service 端在 o...

  • Android进程通信框架Hermes原理探究

    先简单温习下AIDL通信机制: 服务端 创建Service等待客户端发来连接请求。创建AIDL文件,将暴露给客户端...

  • [note] IPC sketch

    1, define AIDL file 2, Server service manifest 中声明Service...

  • Service,AIDL

    服务的运行不依赖于任何用户界面,即使程序被切换到后台,或者用户打开另一个应用,服务仍然能保持独立正常运行。 服务依...

  • 2018-07-06

    service和AIDL service执行与UI进程中,所以不要在service中执行耗时操作。 service...

网友评论

      本文标题:Service AIDL简单使用

      本文链接:https://www.haomeiwen.com/subject/wwlhictx.html