AIDL

前一段时间学习了一哈AIDL今天复习的时候把他发出来
AIDL: Android Interface definition language的缩写,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口。
提到AIDL就必须提到ICP。ICP:interprocess communication :内部进程通信
今天用AndroidStudio来实现,需要两部分,Client和Service。
整体设计思想是:Client调用Service的加法计算方法来计算两个数字的和。很简单有木有。。。。
先写Sevice段很简单,启动一个Service,里面实现一个加法的方法,具体操作如下:
这里写图片描述
在main文件加下新建一个aidl文件,使用该方法生成aidl文件。
这里写图片描述
在该接口里面写入加法的的接口;

int add(int num1, int num2);

在服务端创建Ibinder通过刚才接口的ServiceAidlInterface.Stub{};里面重写add方法。 要实现自己的接口,就从YourInterface.Stub类继承,然后实现相关的方法(可以创建.aidl文件然后实现stub方法而不用在中间编译,Android编译过程会在.java文件之前处理.aidl文件)。在AndroidStudio中要自己Clean一哈生成,自动好像生成的很慢。
Service中的代码:

public class IremoteService extends Service {
    //当客户端绑定的时候调用
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return iBinder;
    }
    private IBinder iBinder = new MyAidl.Stub() {
        @Override
        public int add(int num1, int num2) throws RemoteException {
            Log.d("TAG", "你输入的参数是" + num1 + "和" + num2);
            return num1 + num2;
        }
    };

AIDL文件中的代码:

package com.example.administrator.serviceaidl;

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

interface ServiceAidlInterface {
   //计算两个数的和
     int add(int num1, int num2);
}

之后写Client在咋Main文件夹下新建aidl文件夹,并创建与service端包名一样的Package和.aidl文件如下:
包名和文件名一定一定一定要一样不然不行会出错。
Client端的结构:
这里写图片描述
Service断的结构:
这里写图片描述
对了忘了,在Service端的onbind方法要返回刚才的新建的那个Ibinder
代码如下:

package com.example.administrator.serviceaidl;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class IremoteService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        return iBinder;
    }
    private IBinder iBinder=new ServiceAidlInterface.Stub() {
        @Override
        public int add(int num1, int num2) throws RemoteException {
            return num1+num2;
        }
    };

}

这里要仔细点不然会出错,很麻烦不好找。
那麽客户端如何调用Service端的就是要利用
也是利用bindService来绑定服务获取服务端的AIDL对象来调用add方法。具体如下:

package com.example.administrator.serviceaidlclient;

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.os.RemoteException;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.example.administrator.serviceaidl.ServiceAidlInterface;

public class MainActivity extends Activity  implements View.OnClickListener{
    private ServiceAidlInterface serviceAidl;
    private TextView tv_res;
    private EditText num1;
    private EditText num2;
    private Button btn_add;

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

    //初始化视图
    private void initview() {
        num1 = (EditText) findViewById(R.id.edt_num1);
        num2 = (EditText) findViewById(R.id.edt_num2);
        btn_add = (Button) findViewById(R.id.btn_add);
        tv_res= (TextView) findViewById(R.id.tv_res);
        btn_add.setOnClickListener(this);
    }

    //获取到服务端
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_add:
                int n = Integer.parseInt(num1.getText().toString());
                int m = Integer.parseInt(num2.getText().toString());
                try {
                    //调用远程的服务
                    Log.d("TAG", "n:" + n + "----m:" + m);
                    int res= serviceAidl.add(n,m);
                    tv_res.setText(res+"");
                } catch (RemoteException e) {
                    e.printStackTrace();
                    tv_res.setText("错误啦!");
                }
                break;
        }
    }

    private void bindService() {
        //新版本必须显示启动服务
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.example.administrator.serviceaidl", "com.example.administrator.serviceaidl.IremoteService"));
        bindService(intent, conn, Context.BIND_AUTO_CREATE);

    }
    private ServiceConnection conn=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            serviceAidl=ServiceAidlInterface.Stub.asInterface(service);
        }
        //释放资源
        @Override
        public void onServiceDisconnected(ComponentName name) {
            serviceAidl=null;
        }
    };

    @Override
    protected void onDestroy() {
        unbindService(conn);
        super.onDestroy();
    }
}

再唠叨一哈就是设置intent的时候必须是Service的包名,一定不能错通过intent的 setComponent来指定目的如果有不知道的来这儿
忘了Service端的Manifest文件了补上:

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

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

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service
            android:name=".IremoteService"
            android:enabled="true"
            android:exported="true" >
                <intent-filter>
                    <action android:name="com.example.administrator.serviceaidl.IremoteService"/>
                </intent-filter>
        </service>
        <uses-permission
            android:name="android.permission.BIND_REMOTEVIEWS"></uses-permission>
    </application>

</manifest>

先运行Service段的之后运行Client的效果图下:
这里写图片描述
对于AIDL需要深究的请私密我哦。
需要源码的杵这儿。没有积分的朋友私密我我给GitHub账户。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值