Android 四大组件之一 Service (二)

跨进程通信

AIDL android interface definition language

此应用实现步骤

* 实现步骤
 *  1、定义service
 *  2Manifest.xml中注册
 *              <service android:name=".RemoteService"
 *             android:exported="true">
 *             <intent-filter>
 *                 <action android:name="com.hfzy.mydome0811.remote"/>
 *             </intent-filter>
 *         </service>
 *   3、定义aidl
 *      interface IUser{
 *          boolean checkPhone(String phone);
 *      }
 *			如果有自定义类型
 *          1、自定义类要实现Parcelable接口
 *          2、添加自定义类型的aidl文件
 *              package com.hfzy.mydome0811;
 *              parcelable User;
 *          3、在接口的aidl中要用import导入
 *              import com.hfzy.mydome0811.User;
 *   4、定义IUser.Stub的子类,实现方法,创建对象,在onBind()方法中返回

定义service

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new RemoteBinder();
    }
//远程的服务
    public class RemoteBinder extends IUser.Stub{

        @Override
        public boolean checkPhone(String phone) throws RemoteException {
            return "123".equals(phone);
        }
    }

定义aidl

interface IUser {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     * 可使用的数据类型 int long boolean float double String
     *      其他:如果用自定义类型(需要实现Parcelable接口,前面需要import导入)
     */
    boolean checkPhone(String phone);
}

Manifest.xml中注册

<service android:name=".RemoteService"
            android:exported="true">
            <intent-filter>
                <action android:name="com.hfzy.mydome0811.remote"/>
            </intent-filter>
        </service>

自定义类型

public class User implements Parcelable {
    private String phone;
    private String pwd;
    private String nickname;
    

    protected User(Parcel in) {
        phone = in.readString();
        pwd = in.readString();
        nickname = in.readString();
    }

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

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

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

    //打包
    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(phone);
        parcel.writeString(pwd);
        parcel.writeString(nickname);
    }
添加自定义的aidl文件
package com.hfzy.mydome0811;

parcelable User;

在这里插入图片描述

在接口的aidl中要用import导入
import com.hfzy.mydome0811.User;//自定义类型 需要实现Parcelable接口

外部应用实现过程

*   1、bindService()
 *      intent.setAction("com.hfzy.mydome0811.remote");
 *         intent.setPackage("com.hfzy.mydome0811");
 *         Manifest.xml
 *              <queries>
 *              <package android:name="com.hfzy.mydome0811"/>
 *                  <intent>
 *                       <action android:name="com.hfzy.mydome01.DomeActivity"/>
 *                  </intent>
 *              </queries>
 *     2、复制service的aidl。要保证和service的bao名一致
 *			如果有自定义类型:
 *              要拷贝Service端的java文件,和service的包名一致
 *     3、在Connection中获取接口对象
 *          iUser=IUser.Stub.asInterface(iBinder);
 *          调用接口中的方法

bindService()

private IUser iUser;
private void doBind() {
        Intent intent=new Intent();

        intent.setAction("com.hfzy.mydome0811.remote");
        intent.setPackage("com.hfzy.mydome0811");
        ServiceConnection connection=new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                iUser=IUser.Stub.asInterface(iBinder);
            }

            @Override
            public void onServiceDisconnected(ComponentName componentName) {

            }
        };
        bindService(intent,connection, Context.BIND_AUTO_CREATE);
    }

Manifest.xml中注册

    <queries>
        <package android:name="com.hfzy.mydome0811"/>
        <intent>
            <action android:name="com.hfzy.mydome0811.remote"/>
        </intent>
    </queries>

复制service的aidl。要保证和service的bao名一致

在这里插入图片描述

在Connection中获取接口对象

    private void doCheck() {
        if (iUser!=null){
            String phone=editText.getText().toString();
            try {
                boolean f=iUser.checkPhone(phone);
                Toast.makeText(this, "检查结果是"+f, Toast.LENGTH_LONG).show();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

    }

自定义的类

在这里插入图片描述

文件的包名要和service里面的文件包名相同

Messenger类

基于消息机制,轻量型IPC通信

在服务端,用户端进行各自的编写

service端

 * Service
 *      定义handler--handlerMessage()
 *      定义Messager
 *      public IBinder onBind(Intent intent) {
 *         return service.getBinder();
 *     }
private Handler serverHandler=new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);

            Message m=Message.obtain();//建立消息
            m.arg1=18;
            Log.d("","service======"+msg.arg1);

            try {
                msg.replyTo.send(m);//获取用户端的Messenger对象,并往用户端发送消息
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }
    };
    private Messenger service=new Messenger(serverHandler);//实例化Messenger对象

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return service.getBinder();//获取IBinder对象
    }

在Manifest里面注册

       <service android:name=".MessengerService"
            android:exported="true">
            <intent-filter>
                <action android:name="com.hfzy.mydome0811.messenahe"/>
            </intent-filter>
        </service>

客户端

 * client
 *      1onServiceConnected() 获取service的Messenger的引用
 *      2、根据业务逻辑Messenger的send()---msg.replyto=client Messenger
 *      3、定义Handler
 *      4、定义Messager
private Button button;
private Handler handler=new Handler(){
    @Override
    public void handleMessage(@NonNull Message msg) {//处理服务端发送的消息
        super.handleMessage(msg);
        Log.d("","content======="+msg.arg1);
    }
};

private Messenger messenger=new Messenger(handler);

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

     button=findViewById(R.id.but3);
     button.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View view) {
               Message msg=Message.obtain();
               msg.arg1=2;
               msg.replyTo=messenger;//传输当前messenger对象
             try {
                 serve.send(msg);//通过messenger向服务端发送消息
             } catch (RemoteException e) {
                 e.printStackTrace();
             }
         }
     });
        doService();
    }
    private Messenger serve;
    private ServiceConnection connection=new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                Log.d("","======"+iBinder);
                    serve=new Messenger(iBinder);//实例化Messenger对象
            }
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
            }
        };
    private void doService() {//连接服务端
        Intent intent=new Intent();
        intent.setPackage("com.hfzy.mydome0811");
        intent.setAction("com.hfzy.mydome0811.messenahe");
        bindService(intent,connection,BIND_AUTO_CREATE);
    }

同样也在Manifest中注册

    <queries>
        <package android:name="com.hfzy.mydome0811" />
        <intent>
            <action android:name="com.hfzy.mydome0811.messenahe" />
        </intent>
    </queries>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值