Messenger
服务端
创建Service:
public class MessengerService extends Service {
private static final int MSG_SUM = 0x110;
private Messenger messenger = new Messenger(new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
Message message = Message.obtain(msg);
switch (msg.what) {
case MSG_SUM:
message.what = MSG_SUM;
try {
Thread.sleep(2000);
message.arg2 = msg.arg1 + msg.arg2;
msg.replyTo.send(message);
} catch (InterruptedException | RemoteException e) {
e.printStackTrace();
}
break;
default:
break;
}
super.handleMessage(msg);
}
});
@Nullable
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
}
在Service中创建Messenger实例,通过Message消息机制进行操作,Service的onBind中返回messenger实例的Binder对象。
注册service:
<service
android:name=".MessengerService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.messengerserver" />
</intent-filter>
</service>
此处action值随意设置,后续和intent的action匹配即可。
客户端
public class MainActivity extends AppCompatActivity {
private static final int MSG_SUM = 0x110;
private Button button;
private LinearLayout layout;
private TextView mTvState;
private Messenger mService;
private boolean isConn;
private Messenger mMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case MSG_SUM:
TextView tv = (TextView) layout.findViewById(msg.arg1);
tv.setText(tv.getText() + "=>" + msg.arg2);
break;
}
super.handleMessage(msg);
}
});
private ServiceConnection mConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mService = new Messenger(iBinder);
isConn = true;
mTvState.setText("conn");
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mService = null;
isConn = false;
mTvState.setText("dis");
}
};
private int mA;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent();
intent.setPackage("com.example.messengerserver");
bindService(intent, mConn, BIND_AUTO_CREATE);
mTvState = (TextView) findViewById(R.id.id_tv_callback);
button = (Button) findViewById(R.id.id_btn_add);
layout = (LinearLayout) findViewById(R.id.id_ll_container);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
int a = mA++;
int b = (int) (Math.random() * 100);
TextView tv = new TextView(MainActivity.this);
tv.setText(a + " + " + b + " = caculating ...");
tv.setId(a);
layout.addView(tv);
Message msg = Message.obtain(null, MSG_SUM, a, b);
msg.replyTo = mMessenger;
if (isConn) {
mService.send(msg);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
}
注: ①intent设置:隐式必须声明package为service所在包名(而action不必声明,但若声明则必须和服务端设置的action相同,否则service绑定失败) ②ServiceConnection为连接、断开的回调方法 ③流程: a、客户端与服务端通过service绑定成功后,调用ServiceConnection回调方法,客户端依据返回的binder生成给服务端发送信息的messenger
mService = new Messenger(iBinder);
b、客户端创建message给服务端发送
Message msg = Message.obtain(null, MSG_SUM, a, b);
msg.replyTo = mMessenger;
if (isConn) {
mService.send(msg);
}
c、服务端接收信息进行数据处理并给在message绑定好的Messenger发送信息
message.arg2 = msg.arg1 + msg.arg2;
msg.replyTo.send(message);
发送回客户端后触发handleMessage
AIDL+远程Service
服务端
interface IPersonAidlInterface {
void setName(String name);
void setAge(int age);
String getInfo();
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
}
创建aidl文件夹及包+aidl文件(包名需与java文件夹内包相同) aidl文件创建后,makeProject再继续编写。
public class PersonService extends Service {
public PersonService() {
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new IPersonImpl();
}
public class IPersonImpl extends IPersonAidlInterface.Stub {
private String name;
private int age;
@Override
public void setName(String name) throws RemoteException {
this.name = name;
Log.i("server", name);
}
@Override
public void setAge(int age) throws RemoteException {
this.age = age;
}
@Override
public String getInfo() throws RemoteException {
return "My name is "+name+", age is "+age+"!";
}
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
}
}
创建aidl.stub子类,重写方法逻辑,在Service的onbind返回stub实例。
声明service:
<service android:name=".PersonService"
android:enabled="true"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="com.example.aidlserver" />
</intent-filter>
</service>
此处注意点同messenger
客户端
将服务端创建的aidl文件夹复制到客户端中,再makeProject
public class MainActivity extends AppCompatActivity {
private IPersonAidlInterface iPersonAidlInterface;
TextView textView;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
iPersonAidlInterface = IPersonAidlInterface.Stub.asInterface(iBinder);
try {
iPersonAidlInterface.setName("123");
textView.setText(iPersonAidlInterface.getInfo());
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.text);
Intent intent = new Intent();
intent.setPackage("com.example.aidlserver");
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
}
}
注: ①在ServiceConnection中主要执行iPersonAidlInterface = IPersonAidlInterface.Stub.asInterface(iBinder); ,后续通过iPersonAidlInterface 即可调用服务端方法 ②服务绑定注意点与方法和Messenger相同
对比
Messenger主要通过Message消息机制进行通信,省去了AIDL接口的编写与实现 两者都需要通过Service进行服务端、客户端关系绑定,绑定后再实现通信。
|