第一次写博客,有粗糙之处敬请谅解。
一、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支持数据类型有:
- java的基本数据类型、String、CharSequence。
- List 和 Map ,List和Map 对象的元素必须是AIDL支持的数据类型发。
- 实现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代码连接