AIDL基本使用3—-in out inout的用

在AIDL中客户端和服务端传入参数 是可以设置流向.仅限参数不包含返回值
1. in :客户端可以传入参数到服务到(默认方法)
2. out:服务端修改客户端传入参数对象 会影响客户端的传入实例
3. inout:服务端即可接受客户端参数也可以修改对其客户端实例影响

这个标签在哪?


这里用AIDL基本使用2的Demo作为案例:AIDL基本使用2

在AIDL基本使用2案例中 IMyAidlInterface.aidl 用来作为客户端和服务端交互的接口.

// IMyAidlInterface.aidl
package com.ucoupon.myservice;
import com.ucoupon.myservice2.Book;

interface IMyAidlInterface {

    String bookIn(in Book mbook);
    String bookOut(out Book mbook);
    String bookInout(inout Book mbook);
}

看上面的代码中可以知道.in out inout是用来修饰aidl接口中传入参数.

我们在复习下Book.java 里面有什么

package com.ucoupon.myservice2;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by FMY on 2017/5/18.
 */

public class Book implements Parcelable {

    String name;

    int id;

    public Book(String name, int id) {
        this.name = name;
        this.id = id;
    }

    protected Book(Parcel in) {
        name = in.readString();
        id = in.readInt();
    }

    public static final Creator<Book> CREATOR = new Creator<Book>() {
        @Override
        public Book createFromParcel(Parcel in) {
            return new Book(in);
        }

        @Override
        public Book[] newArray(int size) {
            return new Book[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(id);
    }
}

一个很普通的类有两个字段

  • 来编译看看
    编译出错,出错于自动生成接口java文件.new Book()无法被实例化.
    因为根本没有这个构造方法.
    这里写图片描述

为什么我们在AIDL基本使用的2中没有报错?
继续查看源码

这里写图片描述

如果被修饰方法参数为out那么会自动创建修饰参数的空构造方法
在本例中有如下方法被out修饰:
String bookOut(out Book mbook);

解决办法:创建一个空构造方法

  • 继续编译
    编译又报错
    这里写图片描述

可以看到Book实例化调用readFromParcel方法.可是book没有这个方法.

解决办法:
在Book类中添加此方法.此方法是用于客户端用了out或者inout修饰的方法 中读取服务端修改后的对象的数值在赋值给客户端

package com.ucoupon.myservice2;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by FMY on 2017/5/18.
 */

public class Book implements Parcelable {


....

    public void readFromParcel(Parcel reply) {
        name = reply.readString();
        id = reply.readInt();

    }
    .....
}

修改后编译通过;

然后把文件拷贝到客户端 进行绑定操作 这一步略过


in测试

来看服务段代码

package com.ucoupon.myservice;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;

import com.ucoupon.myservice2.Book;

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate() called");
    }

    //绑定的时候回调
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind() called with: intent = [" + intent + "]");
        return new MyAidlInterface();

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand() called with: intent = [" + intent + "], flags = [" + flags + "], startId = [" + startId + "]");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void unbindService(ServiceConnection conn) {
        Log.d(TAG, "unbindService() called with: conn = [" + conn + "]");
        super.unbindService(conn);
    }

    @Override
    public void onRebind(Intent intent) {
        Log.d(TAG, "onRebind() called with: intent = [" + intent + "]");
        super.onRebind(intent);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG, "onUnbind() called with: intent = [" + intent + "]");
        return super.onUnbind(intent);
    }

    @Override
    public void unregisterReceiver(BroadcastReceiver receiver) {
        Log.d(TAG, "unregisterReceiver() called with: receiver = [" + receiver + "]");
        super.unregisterReceiver(receiver);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy() called");
    }

    @Override
    public void onStart(Intent intent, int startId) {
        Log.d(TAG, "onStart() called with: intent = [" + intent + "], startId = [" + startId + "]");
        super.onStart(intent, startId);
    }

    private static final String TAG = "MyService";

    class MyAidlInterface extends IMyAidlInterface.Stub{


        @Override
        public String bookIn(Book mbook) throws RemoteException {
            Log.d(TAG, "bookIn() called with: mbook = [" + mbook + "]");

            mbook.id = 233;

            return null;
        }

        @Override
        public String bookOut(Book mbook) throws RemoteException {
            Log.d(TAG, "bookout() called with: mbook = [" + mbook + "]");

            mbook.id = 233;
            return null;
        }

        @Override
        public String bookInout(Book mbook) throws RemoteException {
            Log.d(TAG, "bookInout() called with: mbook = [" + mbook + "]");

            mbook.id = 233;
            return null;
        }
    }
}

客户端:

package com.ucoupon.aidlstudy;

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.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.ucoupon.myservice.IMyAidlInterface;
import com.ucoupon.myservice2.Book;

public class MainActivity extends AppCompatActivity {

    private Myconnect myconnect;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //连接管理
        myconnect = new Myconnect();


        //意图
        Intent intent = new Intent();

        intent.setClassName("com.ucoupon.myservice","com.ucoupon.myservice.MyService");

        startService(intent);

        //开始绑定服务
        bindService(intent,myconnect,BIND_AUTO_CREATE);




    }

    private static final String TAG = "MainActivity";

    class Myconnect implements ServiceConnection {

        //连接的成功的时候回调
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected() called with: name = [" + name + "], service = [" + service + "]");


            IMyAidlInterface iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);


            Book mBook = new Book("客户端", -1);

            try {
                Log.e("fmy","客户端没有调用 bookin方法前mBook: name = "+mBook.name+","+" id"+mBook.id);
                iMyAidlInterface.bookIn(mBook);
                Log.e("fmy","客户端调用后 bookin方法后mBook: name = "+mBook.name+","+" id"+mBook.id);
            } catch (RemoteException e) {
                e.printStackTrace();
            }

            //解绑服务
//            unbindService(myconnect);
        }

        //断开连接的时候回调
        @Override
        public void onServiceDisconnected(ComponentName name) {

            Log.d(TAG, "onServiceDisconnected() called with: name = [" + name + "]");
        }
    }
}

结果预测:
根据前言in 可以让客户端传入一个对象给服务端.但是服务端拿到对象后修改对客户端实例是没有效果

运行结果:
客户端:

E/fmy: 客户端没有调用 bookin方法前mBook: name = 客户端, id-1
客户端调用后 bookin方法后mBook: name = 客户端, id-1

服务端:

 mbook = [Book{name='客户端', id=-1}]

从上面的日志可以发现客户端调用前后book实例是没有任何变化.
服务端也正确读取到客户端发送book实例信息.
回过头来再看看bookIn方法.

  @Override
        public String bookIn(Book mbook) throws RemoteException {
            Log.d(TAG, "bookIn() called with: mbook = [" + mbook + "]");

            mbook.id = 233;

            return null;
        }

方法中bookIn对传入的book对象修改了id为233.但是客户端在调用后并有没有影响自身book对象.

out测试

客户端代码和上面in测试差不多,只改变调用bookout方法而已
客户端:

Book mBook = new Book("客户端", -1);

 try {
     Log.e("fmy","客户端没有调用 bookout方法前mBook: name = "+mBook.name+","+" id"+mBook.id);
     iMyAidlInterface.bookOut(mBook);
     Log.e("fmy","客户端调用后 bookout方法后mBook: name = "+mBook.name+","+" id"+mBook.id);
 } catch (RemoteException e) {
     e.printStackTrace();
 }

预期结果:
out定义:服务端无法读取从客户端传入的参数,但可以改变传入的对象,然后对客户端的实例对象有影响

客户端没有调用 bookout方法前mBook: name = 客户端, id-1
客户端调用后 bookout方法后mBook: name = null, id233

服务端:

mbook = [Book{name='null', id=0}]

判断正确:因为out是客户端无法传入参数给服务端,所以服务端的book参数都为默认值.
这时服务端修改book的id为233.然后把服务端的book传回.所以调用后客户端的name为空 id为233

AIDL基本使用4—-linkToDeath和unlinkToDeath

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Android 应用程序中使用 AIDL,您需要执行以下步骤: 1. 创建 AIDL 接口文件 AIDL 接口文件定义了客户端和服务端之间的通信接口。在在 Android Studio 的 app 目录下创建一个名为 aidl 的文件夹,然后在该文件夹下创建一个 .aidl 文件。例如,我们可以创建一个名为 IMyAidlInterface.aidl 的文件。 2. 定义 AIDL 接口 在 IMyAidlInterface.aidl 文件中,我们可以定义客户端和服务端之间需要交换的数据类型和方法。例如: ``` // IMyAidlInterface.aidl package com.example.myaidl; // Declare any non-default types here with import statements interface IMyAidlInterface { int add(int a, int b); } ``` 在上面的例子中,我们定义了一个名为 IMyAidlInterface 的接口,该接口包含一个 add(int a, int b) 方法,用于计算两个整数的和。 3. 实现 AIDL 接口 在服务端应用程序中,我们需要实现上述定义的 AIDL 接口。在服务端应用程序的 Java 代码中,我们需要实现 IMyAidlInterface.Stub 类,它是一个抽象类,继承自 Binder 类。在 IMyAidlInterface.Stub 类中,我们需要实现 add(int a, int b) 方法。例如: ``` public class MyAidlService extends Service { private final IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() { @Override public int add(int a, int b) throws RemoteException { return a + b; } }; @Nullable @Override public IBinder onBind(Intent intent) { return mBinder; } } ``` 在上面的例子中,我们实现了 add(int a, int b) 方法,该方法计算两个整数的和,并返回结果。 4. 在客户端应用程序中调用 AIDL 接口 在客户端应用程序中,我们需要绑定服务,以获取服务端的实例。然后,我们可以调用服务端的方法。例如: ``` public class MainActivity extends AppCompatActivity { private IMyAidlInterface mIMyAidlInterface; private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { mIMyAidlInterface = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(); intent.setComponent(new ComponentName("com.example.myaidl", "com.example.myaidl.MyAidlService")); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); int result = mIMyAidlInterface.add(1, 2); Log.d("MainActivity", "Result: " + result); } } ``` 在上面的例子中,我们绑定服务,以获取服务端的实例。然后,我们调用服务端的 add(int a, int b) 方法,计算两个整数的和,并输出结果。 以上就是使用 AIDL 在不同的应用程序之间进行通信的基本步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值