Android AIDL 学习 (客户端)

接上移篇 Android AIDL 学习(服务端)我们今天来看看客户端怎么实现调用。

我们还是先创建个客户端项目,AClient

开发环境:Android Studio 3.6.2

保存的地方,你根据你的习惯随便找个地方保存。

Android AIDL 学习 (客户端)_第1张图片

 Android AIDL 学习 (客户端)_第2张图片

 要实现AIDL的调用,需要有AIDL的服务放提供为我们AIDL接口文件,还有必须的类别才行。

那我们BService服务端,需要提供给我慢AIDL接口,还有用到的Book类的定义。

还需要提供给我们调用服务的action:com.example.bservice.bookService

服务器提供的AIDL接口:IMyBookManager

// IMyBookManager.aidl
package com.example.bservice;

// Declare any non-default types here with import statements
//需要采用全部包名的引入。
import com.example.bservice.Book;

//需要说明我们引入的book 是个序列化的类。
parcelable Book;

interface IMyBookManager {
    /**
     * 默认添加的基础类型接口,不用可以删掉
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

    String login(String userName, String pwd);

    Book queryByName(String bookName);
}

服务端提供Book类的定义

package com.example.bservice;

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

import androidx.annotation.NonNull;

public class Book implements Parcelable {
    private int price;
    private String name = "";

    public Book(){}

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

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

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

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @NonNull
    @Override
    public String toString() {
        return "name:" + name + ",price:" + price;
    }

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

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

我们把这两个类添加到我们的项目中

在main右键选择新建一个文件夹,命名为aidl

Android AIDL 学习 (客户端)_第3张图片

Android AIDL 学习 (客户端)_第4张图片

在didl上点击右键新建包 com.example.bservice 这个报名就是服务提供给我们AIDL文件的报名。必须要一样。

Android AIDL 学习 (客户端)_第5张图片

Android AIDL 学习 (客户端)_第6张图片

Android AIDL 学习 (客户端)_第7张图片

在这个包中我们添加服务端给我们的aidl 文件

Android AIDL 学习 (客户端)_第8张图片 Android AIDL 学习 (客户端)_第9张图片

然后把服务端的接口内容粘贴到文件中。 Android AIDL 学习 (客户端)_第10张图片

处理完了接口文件,我们来处理接口文件返回来的类Book。

在src\main\java\新建包 com.example.bservice;

Android AIDL 学习 (客户端)_第11张图片

Android AIDL 学习 (客户端)_第12张图片

在新建的包上右键新建Book类。

Android AIDL 学习 (客户端)_第13张图片

Android AIDL 学习 (客户端)_第14张图片

 把服务端提供的Book类的结构保存到文件。

Android AIDL 学习 (客户端)_第15张图片

 到这类服务器提供给我们的接口文件、类文件,我们按照要求一模一样的添加到了我们的项目中,那接下来就是要如何的调用接口了。

既然AIDL是采用绑定服务的方式向外提供服务,那我们第一步要做的就是需要启动绑定服务,服务启动后,获取返回的binder对象。获取到对象后就可以通过调用对象提供的接口来完成相应的工作。

我们实现一个简单的调用功能,有个连接按钮来绑定服务,有个登录来进行模拟登录验证,有个图书的查询功能,并显示返回的图书信息。

好了这个功能我就从mainactivity的布局文件中实现。

代码如下




    

Android AIDL 学习 (客户端)_第16张图片

这就是一个连接AIDL的学习示例不要太纠结具体的功能是否有意义。

界面定义完成之后,我们来看看具体的diam实现

我先来定义下我需要的控件。

package com.example.aclient;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private Button btnConnection;
    private TextView txtConnectionState;
    private EditText etName;
    private EditText etPwd;
    private Button btnLogin;
    private TextView etLoginState;
    private EditText etBookInfo;
    private Button btnQuery;
    private EditText etBookName;

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

        initViews();
    }

    private void initViews(){
        btnConnection = findViewById(R.id.btnConnection);
        txtConnectionState = findViewById(R.id.txtConnectionState);
        etName = findViewById(R.id.etName);
        etPwd = findViewById(R.id.etPwd);
        btnLogin = findViewById(R.id.btnLogin);
        etLoginState = findViewById(R.id.etLoginState);
        etBookInfo = findViewById(R.id.etBookInfo);
        btnQuery = findViewById(R.id.btnQuery);
        etBookName = findViewById(R.id.etBookName);
    }
}

定义好控件之后,我们先来看看连接怎么实现。给btnConnection 添加点击事件,从中调用bindService来开启服务。

 boolean bindService( Intent service,   ServiceConnection conn,  int flags);

开发服务需要三个参数

service 传入要绑定的服务。

conn 连接成功后返回绑定对象。

在写服务端的时候,服务端有定义了一个action:com.example.bservice.bookService

定义一个ServiceConnection 的对象conn;

public class MainActivity extends AppCompatActivity {

//控件定义
......

    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

......


}

再定义个IMyBookManager用于接受连接返回的对象,后续的调用也需要此对象。

public class MainActivity extends AppCompatActivity {

//控件定义
......

private IMyBookManager bookManager = null;

    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            bookManager = IMyBookManager.Stub.asInterface(service);
            txtConnectionState.setText("连接成功!");
        }

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

......


}

我来实现btnConnection 按钮的点击事件。

        btnConnection.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent intent = new Intent();
                intent.setAction("com.example.bservice.bookService");
                intent.setPackage("com.example.bservice");
                bindService(intent, conn, Context.BIND_AUTO_CREATE);
                
            }
        });

在事件中,我们定义了一个intent 并发送bindSevice进行绑定。

我来实现登录的事件

btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(bookManager == null)
                {
                    Toast.makeText(MainActivity.this, "还没有绑定服务。", Toast.LENGTH_LONG).show();
                    return;
                }
                if(etName.getText().toString().isEmpty() || etPwd.getText().toString().isEmpty()){
                    Toast.makeText(MainActivity.this, "用户名或密码不能为空。", Toast.LENGTH_LONG).show();
                    return;
                }

                try {
                    String resStr = bookManager.login(etName.getText().toString(), etPwd.getText().toString());

                    if(resStr.compareToIgnoreCase("success") == 0){
                        etLoginState.setText("登录成功!");
                   } else{
                        throw new RemoteException("登录失败");
                    }
                } catch (RemoteException e) {
                    e.printStackTrace();
                    etLoginState.setText("登录成功!");
                }

            }
        });

最后我们来实现图书查询的事件:

btnQuery.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(bookManager == null)
                {
                    Toast.makeText(MainActivity.this, "还没有绑定服务。", Toast.LENGTH_LONG).show();
                    return;
                }
                if(etBookName.getText().toString().isEmpty()){
                    Toast.makeText(MainActivity.this, "请输入您要查找的图书。", Toast.LENGTH_LONG).show();
                    return;
                }
                try {
                    Book book = bookManager.queryByName(etBookName.getText().toString());

                    if(book != null){
                        etBookInfo.setText(book.toString());
                    } else{
                        throw new RemoteException("查询失败");
                    }
                } catch (RemoteException e) {
                    e.printStackTrace();
                    etBookInfo.setText("查询失败");
                }
            }
        });

全部的代码:

package com.example.aclient;

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

import androidx.appcompat.app.AppCompatActivity;

import com.example.bservice.Book;
import com.example.bservice.IMyBookManager;

public class MainActivity extends AppCompatActivity {

    private Button btnConnection;
    private TextView txtConnectionState;
    private EditText etName;
    private EditText etPwd;
    private Button btnLogin;
    private TextView etLoginState;
    private EditText etBookInfo;
    private Button btnQuery;
    private EditText etBookName;


    private IMyBookManager bookManager = null;

    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            bookManager = IMyBookManager.Stub.asInterface(service);
            txtConnectionState.setText("连接成功!");
        }

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

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

        initViews();
    }

    private void initViews(){
        btnConnection = findViewById(R.id.btnConnection);
        btnConnection.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent intent = new Intent();
                intent.setAction("com.example.bservice.bookService");
                intent.setPackage("com.example.bservice");
                bindService(intent, conn, Context.BIND_AUTO_CREATE);

            }
        });

        txtConnectionState = findViewById(R.id.txtConnectionState);
        etName = findViewById(R.id.etName);
        etPwd = findViewById(R.id.etPwd);
        btnLogin = findViewById(R.id.btnLogin);
        btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(bookManager == null)
                {
                    Toast.makeText(MainActivity.this, "还没有绑定服务。", Toast.LENGTH_LONG).show();
                    return;
                }
                if(etName.getText().toString().isEmpty() || etPwd.getText().toString().isEmpty()){
                    Toast.makeText(MainActivity.this, "用户名或密码不能为空。", Toast.LENGTH_LONG).show();
                    return;
                }

                try {
                    String resStr = bookManager.login(etName.getText().toString(), etPwd.getText().toString());

                    if(resStr.compareToIgnoreCase("success") == 0){
                        etLoginState.setText("登录成功!");
                   } else{
                        throw new RemoteException("登录失败");
                    }
                } catch (RemoteException e) {
                    e.printStackTrace();
                    etLoginState.setText("登录成功!");
                }

            }
        });

        etLoginState = findViewById(R.id.etLoginState);
        etBookInfo = findViewById(R.id.etBookInfo);
        btnQuery = findViewById(R.id.btnQuery);
        btnQuery.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(bookManager == null)
                {
                    Toast.makeText(MainActivity.this, "还没有绑定服务。", Toast.LENGTH_LONG).show();
                    return;
                }
                if(etBookName.getText().toString().isEmpty()){
                    Toast.makeText(MainActivity.this, "请输入您要查找的图书。", Toast.LENGTH_LONG).show();
                    return;
                }
                try {
                    Book book = bookManager.queryByName(etBookName.getText().toString());

                    if(book != null){
                        etBookInfo.setText(book.toString());
                    } else{
                        throw new RemoteException("查询失败");
                    }
                } catch (RemoteException e) {
                    e.printStackTrace();
                    etBookInfo.setText("查询失败");
                }
            }
        });
        etBookName = findViewById(R.id.etBookName);
    }
}

运行结果

Android AIDL 学习 (客户端)_第17张图片

 

你可能感兴趣的:(Android,android)