本篇实现两个应用通过AIDL进行通信Demo
1.应用Service_Car 模拟汽车当前速度变化,传递给应用Client_Phone
2.应用Client_Phone可以改变应用Service_Car 的汽车状态
应用Service_Car
应用Client_Phone
1. 首先给Service_Car添加aidl文件
package com.neusoft.dx.service_car;
// Declare any non-default types here with import statements
interface Icarstate {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);//默认的,删了也无妨
//
void setstate(String s);
//
int getSpeed();
}
2. build project
3.添加Servie
package com.neusoft.dx.service_car;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import java.util.Random;
public class MyCarService extends Service {
private String TAG ="MyCarService";
private int SPEED;
private String CAR_STATE;
public MyCarService() {
}
@Override
public void onCreate() {
super.onCreate();
speedrun();
}
//模拟汽车运行
private void speedrun(){
new Thread(new Runnable(){
@Override
public void run() {
while (true){
SPEED = new Random().nextInt(70-60+1)+60;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//传递给Acitvity
Intent intent = new Intent();
intent.setAction("speed get");
intent.putExtra("SPEED", SPEED);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
sendBroadcast(intent);
}
}
}).start();
}
@Override
public IBinder onBind(Intent intent) {
return new Icarstate.Stub() {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
@Override
public void setstate(String s) throws RemoteException {
CAR_STATE = s;
Log.e(TAG, "setstate: "+CAR_STATE );
Intent intent = new Intent();
intent.setAction("state get");
intent.putExtra("STATE", CAR_STATE);
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
sendBroadcast(intent);
}
@Override
public int getSpeed() throws RemoteException {
return SPEED;
}
};
}
}
4.MainActivity绑定服务
package com.neusoft.dx.service_car;
import androidx.appcompat.app.AppCompatActivity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
private ImageView iv_state;
private TextView tv_speed;
private int SPEED;
private String STATE;
private Message message,message2;
private Icarstate icarstate;
private MyServiceConnection connection;
private MyCarService myCarService;
private class MyServiceConnection implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
icarstate = (Icarstate) service;
Log.e("A", "onServiceConnected: ");
if (icarstate!=null){
Log.e("B", "onServiceConnected: success ");
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv_state=findViewById(R.id.iv_state);
tv_speed=findViewById(R.id.tv_speed);
//new
connection = new MyServiceConnection();
boolean res = bindService(new Intent(this, MyCarService.class),
connection,
Context.BIND_AUTO_CREATE);
Log.w("tag_main_oncrete", "bind result: "+res );
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("speed get");
registerReceiver(receiver, intentFilter);
IntentFilter intentFilter2 = new IntentFilter();
intentFilter2.addAction("state get");
registerReceiver(receiver2, intentFilter2);
}
private final Handler mHandler = new Handler(message ->{
switch (message.what){
case 1:
tv_speed.setText(message.obj+"KM/H");
break;
case 2:
if (message.obj.equals("car")){
iv_state.setImageResource(R.drawable.car);
}
else if(message.obj.equals("plane")){
iv_state.setImageResource(R.drawable.plane);
}
else if(message.obj.equals("work")){
iv_state.setImageResource(R.drawable.work);
}
break;
}
return true;
});
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
//广播接收者这里写的好冗余,这里达咩 T~T
//广播接受者
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Log.e("RECEIVER", "onReceive: " +intent.getIntExtra("SPEED", 0));
SPEED =intent.getIntExtra("SPEED", 0);
message= new Message();
message.what=1;
message.obj=SPEED;
mHandler.sendMessage(message);
}
};
//广播接受者2
BroadcastReceiver receiver2 = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.e("RECEIVER2", "onReceive: " +intent.getStringExtra("STATE"));
STATE =intent.getStringExtra("STATE");
message2= new Message();
message2.what = 2;
message2.obj=STATE;
mHandler.sendMessage(message2);
}
};
}
5.布局文件
`<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/iv_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/car"
app:layout_constraintBottom_toTopOf="@+id/guideline5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline4"
app:layout_constraintTop_toTopOf="@+id/guideline3"
/>
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Good afternoon, master!"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.464"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Current speed:"
app:layout_constraintBottom_toTopOf="@+id/guideline3"
app:layout_constraintEnd_toStartOf="@+id/guideline4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline2" />
<TextView
android:id="@+id/tv_speed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:text="60KM/H"
android:textColor="@color/black"
android:textSize="33sp"
app:layout_constraintBottom_toTopOf="@+id/guideline3"
app:layout_constraintStart_toStartOf="@+id/guideline4"
app:layout_constraintTop_toTopOf="@+id/guideline2" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="89dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="238dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="159dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="405dp" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Current State:"
app:layout_constraintBottom_toTopOf="@+id/guideline5"
app:layout_constraintEnd_toStartOf="@+id/guideline4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline3" />
</androidx.constraintlayout.widget.ConstraintLayout>`
6.在AndroidManifest中添加标签
7.图片就自己找三个图片:驾驶状态、工作状态、飞行模式
到这里Service_Car端就写完了
8.将Service_Car的AIDL文件复制到Client_Phone工程上
此处需要注意包名一致!!
9.然后在MainActivity创建AIDL连接
package com.neusoft.dx.client_phone;
import androidx.appcompat.app.AppCompatActivity;
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.util.Log;
import android.view.View;
import android.widget.Button;
import com.neusoft.dx.service_car.Icarstate;
public class MainActivity extends AppCompatActivity {
private Button button;
private String state[]={"car","work","plane"};//work plane car
private int i=0;
private Icarstate icarstate;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
icarstate = Icarstate.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
icarstate = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.button);
Intent intent = new Intent();
intent.setAction("servicecar");//这里是第6部图片中添加的标签
intent.setPackage("com.neusoft.dx.service_car");
boolean result = bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
Log.e("aidl连接", "onCreate:result= "+result );//这里返回连接结果
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Log.e("当前车速", ": "+ icarstate.getSpeed()+"KM/H" );
icarstate.setstate(state[i]);
//这里设计有些问题,因为初始的状态图片就是小汽车,
//然后第一次点击按钮仍然发送的是小汽车,所以需要点击两次按钮才能看出效果,
//这里不是没成功哦~
if (i==2){
i=0;
}else{
i++;
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
}
10.Client_Phone的布局文件
就是一个简单的按钮,点击以此,可以打出当前速度的log,然后改变汽车端的状态图片
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="137dp"
android:text="改变驾驶状态"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
大功告成,快去试试吧,本篇只是一个代码记录,每一步的作用还需自行体会,因为我也说不好哈哈哈,拜拜~