# Android LocalSocket and AIDL 传输对象

第一次写博客,有粗糙之处敬请谅解。
一、LocalSocket使用方法

LocalSocket 跟Socket的使用差不多。LocalSocket与LocalServerSocket创建相同的嵌套字进行连接传输。
嵌套字是字符串:

public static final String LOCALSOCKET_ADDRESS = "muhaitian_localsocket";

创建服务端,在线程中通过循环来监听客户端的请求连接。

public class LocalSocketServer {
    public static final String LOCALSOCKET_ADDRESS = "muhaitian_localsocket";
    private LocalServerSocket mLocalServerSocket;
    private ExecutorService ListenLocalSocketClient;
    public LocalSocketServer (){
        try {
            mLocalServerSocket = new LocalServerSocket(LOCALSOCKET_ADDRESS);
        } catch (IOException e) {
            e.printStackTrace();
        }

        ListenLocalSocketClient = Executors.newSingleThreadExecutor();
    }
    public void startListenLocalSocket(){
        ListenLocalSocketClient.execute(new ListeningRunnable());
    }
    class ListeningRunnable implements Runnable {
      @Override
      puvlic void run(){
         //通过死循环一直监听Client端的请求连接
         while(true){
         ocalSocket localSocket = null;
                try {
                    localSocket = mLocalServerSocket.accept();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                if (localSocket != null) {
               //这里处理传过来的内容
                }
         }
      }
    }
}

创建Client

public class LocalSocketClient {

    private ExecutorService sendTestThread;

    public LocalSocketClient() {
        sendTestThread = Executors.newSingleThreadExecutor();
    }
    public void startSendInfo(TestLocalSocket testLocalSocket){
        sendTestThread.execute(new sendTestRunnable(testLocalSocket));
    }
    class sendTestRunnable implements Runnable {
        @Override
        public void run() {
           ....
        }
    }
}

二、AIDL 中in、out、inout使用
进本的进程间数据共享与通信使用aidl一般使用的是基本类型,也可以使用对象进行传输,但是必须要在类前面添加修饰符。
aidl支持数据类型有:

  1. java的基本数据类型、String、CharSequence。
  2. List 和 Map ,List和Map 对象的元素必须是AIDL支持的数据类型发。
  3. 实现android.os.Parcelable 接口的类,这个需要import。
    修饰符有以下几种:
    in:客户端参数传入(服务端修改后客户端数据不会被修改)
    out:服务端参数传入(客户端传入的参数到服务端会是一个空参数,在服务端进行修改,会生效到客户端。无论客户端传入的参数是否为空,传到服务端这个对象会被变成空对象)
    inout:这个可以叫输入输出参数,客户端可输入、服务端也可输入。客户端输入了参数到服务端后,服务端也可对该参数进行修改等,最后在客户端上得到的是服务端输出的参数。

服务端
客户端与服务端创建相同*.aidl文件,包名与类名必须相同。
定义AIDL接口

package com.muhaitian.record;
// Declare any non-default types here with import statements

import com.muhaitian.record.entity.Student;//注意引用

interface ITestAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */

    Student sendInStudent(in Student student);
    Student sendOutStudent(out Student student);
    Student sendInOutStudent(inout Student studend);
}

实现Parcelable 的类进行序列化。

package com.muhaitian.record.entity;

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

public class Student implements Parcelable{
    private String Name;
    private String StudentID;
    private int Age;
    private boolean Male;

    public Student(){}

    protected Student(Parcel in) {
        Name = in.readString();
        StudentID = in.readString();
        Age = in.readInt();
        Male = in.readByte() != 0;
    }

    public void readFromParcel(Parcel parcel){
        Name = parcel.readString();
        StudentID = parcel.readString();
        Age = parcel.readInt();
        Male = parcel.readByte() != 0;
    }

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

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

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    public String getStudentID() {
        return StudentID;
    }

    public void setStudentID(String studentID) {
        StudentID = studentID;
    }

    public int getAge() {
        return Age;
    }

    public void setAge(int age) {
        Age = age;
    }

    public boolean isMale() {
        return Male;
    }

    public void setMale(boolean male) {
        Male = male;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(Name);
        dest.writeString(StudentID);
        dest.writeInt(Age);
        dest.writeByte((byte) (Male ? 1 : 0));
    }
}

做到这一步还不够还要必须创建一个与Student类名以及包名相同的aidl,否则编译不过,否则会报找不到
student类

这里写图片描述

这里写图片描述

// IStudentInterface.aidl
package com.muhaitian.record.entity;

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

parcelable Student;//parcelable 必须小写

一般服务端都会实现在service中。

package com.muhaitian.record.service;

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

import com.muhaitian.record.ITestAidlInterface;
import com.muhaitian.record.entity.Student;

public class TestAidlService extends Service {

    private final String TAG = TestAidlService.class.getSimpleName();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return iBind;
    }

    private final ITestAidlInterface.Stub iBind = new ITestAidlInterface.Stub() {
        @Override
        public Student sendInStudent(Student student) throws RemoteException {
            Log.d(TAG, "sendInStudent: " + student.getName() + " | " + student.getStudentID() + " | " + student.getAge());
            student.setStudentID("004");
            return student;
        }

        @Override
        public Student sendOutStudent(Student student) throws RemoteException {
            Log.d(TAG, "sendOutStudent: " + student.getName() + " | " + student.getStudentID() + " | " + student.getAge());
            student.setStudentID("005");
            return student;
        }

        @Override
        public Student sendInOutStudent(Student student) throws RemoteException {
            Log.d(TAG, "sendInOutStudent: " + student.getName() + " | " + student.getStudentID() + " | " + student.getAge());
            student.setStudentID("006");
            return student;
        }
    };

}

到此服务端代码写完了。
客户端

复制服务端的aidl和student类到客户端注意(注意包名和类名要相同),连接服务端,获取aidl的实例,然后调用方法。
连接服务端的类

package com.muhaitian.record.localsocket;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import com.muhaitian.record.ILocalSocketAidlInterface;
import com.muhaitian.record.ITestAidlInterface;

public class BindService {

    private final String TAG = "BindService";

    private Context mContext;
    private ILocalSocketAidlInterface mILocalSocketAidlInterface;
    private ITestAidlInterface mITestAidlInterface;
    private LocalsocketConnection mLocalsocketConnection;
    private AidlConnection mAidlConnection;
    private MyHander myHander;
    public BindService(Context context){
        HandlerThread mm = new HandlerThread("bind Aidl");
        mm.start();
        myHander = new MyHander(mm.getLooper());
        mContext = context;
    }

    public boolean startBindLocalSocketService(Intent intent){
        boolean results = false;
        mLocalsocketConnection = new LocalsocketConnection();
        results = mContext.bindService(intent,mLocalsocketConnection,Context.BIND_AUTO_CREATE);

        return results;
    }

    public boolean startBindAidlService(Intent intent){
        boolean results = false;
        mAidlConnection  =new AidlConnection();
        results = mContext.bindService(intent,mAidlConnection,Context.BIND_AUTO_CREATE);
        if(getITestAidlInterface()==null){
            myHander.sendEmptyMessageDelayed(99,500);
        }
        return results;
    }

    class LocalsocketConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mILocalSocketAidlInterface = ILocalSocketAidlInterface.Stub.asInterface(service);
        }

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

    class AidlConnection implements ServiceConnection{

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected: service=="+service);
            mITestAidlInterface = ITestAidlInterface.Stub.asInterface(service);
            Log.d(TAG, "onServiceConnected: mITestAidlInterface=="+mITestAidlInterface);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "onServiceDisconnected: ");
            mITestAidlInterface = null;
        }
    }

    public ILocalSocketAidlInterface getILocalSocketAidlInterface() {
        return mILocalSocketAidlInterface;
    }

    public ITestAidlInterface getITestAidlInterface() {
        Log.d(TAG, "getITestAidlInterface: mITestAidlInterface=="+mITestAidlInterface);
        return mITestAidlInterface;
    }

    class MyHander extends Handler{
        public MyHander(Looper looper){
            super(looper);
        }
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if(msg.what==99){
                if(getITestAidlInterface()==null){
                    Log.d(TAG, "handleMessage: myHander.sendEmptyMessageDelayed(99,300);");
                    myHander.sendEmptyMessageDelayed(99,3000);
                }else {
                    myHander.removeMessages(99);
                }
            }
        }
    }
}

调用到服务端

package com.muhaitian.record;

import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.muhaitian.record.entity.Student;
import com.muhaitian.record.localsocket.BindService;

public class AidlTestActivity extends AppCompatActivity {
    private final String TAG = AidlTestActivity.class.getSimpleName();
    private Button InTest, OutTest, InOutTest;
    private TextView InBeforInfo, InAfterInfo, OutBeforeInfo, OutAfterInfo, InOutBeforeInfo, InOutAfterInfo;
    private Student InBeforeSt, InAfterSt, OutBeforeSt, OutAfterSt, InOutBeforeSt, InOutAfterSt;
    private BindService mBindService;

    private final String AIDL_SERVICE_COMPONENT = "com.muhaitian.record/com.muhaitian.record.service.TestAidlService";


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

        Intent intent = new Intent();
        ComponentName Name = ComponentName.unflattenFromString(AIDL_SERVICE_COMPONENT);
        intent.setComponent(Name);

        initData(intent);
        Initwidget();
    }

    private void initData(Intent intent) {
        if (intent != null) {
            mBindService = new BindService(getApplicationContext());
            boolean results = mBindService.startBindAidlService(intent);
            Log.d(TAG, "initData: results==" + results);
        }
        InBeforeSt = new Student();
        InBeforeSt.setName("wangkang");
        InBeforeSt.setAge(24);
        InBeforeSt.setMale(true);
        InBeforeSt.setStudentID("001");
        InAfterSt = new Student();

        OutBeforeSt = new Student();
        OutBeforeSt.setName("muhaitian");
        OutBeforeSt.setAge(26);
        OutBeforeSt.setMale(true);
        OutBeforeSt.setStudentID("002");
        OutAfterSt = new Student();

        InOutBeforeSt = new Student();
        InOutBeforeSt.setName("lizihai");
        InOutBeforeSt.setAge(27);
        InOutBeforeSt.setMale(true);
        InOutBeforeSt.setStudentID("003");
        InOutAfterSt = new Student();
    }

    private void Initwidget() {
        InBeforInfo = (TextView) findViewById(R.id.InBeforeInfo);
        InAfterInfo = (TextView) findViewById(R.id.InAfterInfo);
        OutBeforeInfo = (TextView) findViewById(R.id.OutBeforeInfo);
        OutAfterInfo = (TextView) findViewById(R.id.OutAfterInfo);
        InOutBeforeInfo = (TextView) findViewById(R.id.InOutBeforeInfo);
        InOutAfterInfo = (TextView) findViewById(R.id.InOutAfterInfo);

        InBeforInfo.setText("Name==" + InBeforeSt.getName() + " | Student==" + InBeforeSt.getStudentID() + " | Age==" + InBeforeSt.getAge());
        OutBeforeInfo.setText("Name==" + OutBeforeSt.getName() + " | Student==" + OutBeforeSt.getStudentID() + " | Age==" + OutBeforeSt.getAge());
        InOutBeforeInfo.setText("Name==" + InOutBeforeSt.getName() + " | Student==" + InOutBeforeSt.getStudentID() + " | Age==" + InOutBeforeSt.getAge());

        InTest = (Button) findViewById(R.id.InTest);
        InTest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    InAfterSt = mBindService.getITestAidlInterface().sendInStudent(InBeforeSt);
                    InAfterInfo.setText("InBeforeSt: Name=" + InBeforeSt.getName() + " | ID==" + InBeforeSt.getStudentID() + " | Age=" + InBeforeSt.getAge() + "\n" +
                            "InAfterSt: Name=" + InAfterSt.getName() + " | ID==" + InAfterSt.getStudentID() + " | Age=" + InAfterSt.getAge() + "\n"
                    );
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
        OutTest = (Button) findViewById(R.id.OutTest);
        OutTest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    OutAfterSt = mBindService.getITestAidlInterface().sendOutStudent(OutBeforeSt);
                    OutAfterInfo.setText("OutBeforeSt: Name=" + OutBeforeSt.getName() + " | ID==" + OutBeforeSt.getStudentID() + " | Age=" + OutBeforeSt.getAge() + "\n" +
                            "OutAfterSt: Name=" + OutAfterSt.getName() + " | ID==" + OutAfterSt.getStudentID() + " | Age=" + OutAfterSt.getAge() + "\n"
                    );
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
        InOutTest = (Button) findViewById(R.id.InOutTest);
        InOutTest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    InOutAfterSt = mBindService.getITestAidlInterface().sendInOutStudent(InOutBeforeSt);
                    InOutAfterInfo.setText("InOutBeforeSt: Name=" + InOutBeforeSt.getName() + " | ID==" + InOutBeforeSt.getStudentID() + " | Age=" + InOutBeforeSt.getAge() + "\n" +
                            "InOutAfterSt: Name=" + InOutAfterSt.getName() + " | ID==" + InOutAfterSt.getStudentID() + " | Age=" + InOutAfterSt.getAge() + "\n"
                    );
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });


    }

}

至此aidl用法完成。
这两个的demo源码连接:github代码连接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值