下面是服务端和客户端互相通讯:
一 :客户端
-
1.创建服务端工程
image.png
在指定包名:com.custom.binder 下 创建Interface.aidl
- 定义接口类型,回调方法:
interface ILoginInterface {
// 登录
void login();
// 登录返回
void loginCallback(boolean loginStatus, String loginUser);
}
- 定义客户端service用于接收服务端回调通讯
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return new ILoginInterface.Stub() {
@Override
public void login() throws RemoteException {
}
@Override
public void loginCallback(boolean loginStatus, String loginUser) throws RemoteException {
Log.e("netease >>> ", "loginStatus: " + loginStatus + " / loginUser: " + loginUser);
}
};
}
}
- 注册服务,点击按钮调用服务端,打开服务端界面
public class MainActivity extends Activity {
// 模拟用户名和密码 的值
private final static String NAME = "netease";
private final static String PWD = "163";
private EditText nameEt;
private EditText pwdEt;
private boolean isStartRemote; // 是否开启跨进程通信
private ILoginInterface iLogin; // AIDL定义接口
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); // 隐藏标题
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN); // 设置全屏
setContentView(R.layout.activity_main);
nameEt = findViewById(R.id.nameEt);
pwdEt = findViewById(R.id.pwdEt);
initBindService();
}
public void initBindService() {
Intent intent = new Intent();
// 设置Server应用Action
intent.setAction("BinderA_Action");
// 设置Server应用包名(5.1+要求)
intent.setPackage("com.netease.binder.a");
// 开始绑定服务
bindService(intent, conn, BIND_AUTO_CREATE);
// 标识跨进程绑定
isStartRemote = true;
}
// 服务连接
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iLogin = ILoginInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
// 点击事件
public void startLogin(View view) {
final String name = nameEt.getText().toString();
final String pwd = pwdEt.getText().toString();
if (TextUtils.isEmpty(name) || TextUtils.isEmpty(pwd)) {
showToast("请输入用户名或密码...");
return;
}
// 模拟登录状态加载...
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("登录");
progressDialog.setMessage("正在登录中...");
progressDialog.show();
new Thread(new Runnable() {
@Override
public void run() {
SystemClock.sleep(2000);
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
boolean isLoginSuccess = false;
if (NAME.equals(name) && PWD.equals(pwd)) {
showToast("QQ登录成功!");
isLoginSuccess = true;
finish();
} else {
showToast("QQ登录失败!");
}
progressDialog.dismiss();
iLogin.loginCallback(isLoginSuccess, NAME);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
}).start();
}
private void showToast(String text) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (isStartRemote) {
// 解绑服务,一定要记得解绑服务,否则可能会报异常(服务连接资源异常)
unbindService(conn);
}
}
}
二 :服务端
-
1.创建服务端AIDL 目录(注意次包名和服务端包名保证一致)
image.png - 2.新建Interface.aidl
interface ILoginInterface {
// 登录
void login();
// 登录返回
void loginCallback(boolean loginStatus, String loginUser);
}
- 3.新建服务端service 监听回调:下面客户端调服务端后打开对应服务端界面
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return new ILoginInterface.Stub() {
@Override
public void login() throws RemoteException {
Log.e("netease >>> ", "BinderB_MyService");
// 单项通信有问题,真实项目双向通信,双服务绑定
serviceStartActivity();
}
@Override
public void loginCallback(boolean loginStatus, String loginUser) throws RemoteException {
}
};
}
/**
* 在Service启动Activity,需要配置:.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
*/
private void serviceStartActivity() {
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
- 4.服务端初始化服务,调用客户端代码
public class MainActivity extends Activity {
private boolean isStartRemote; // 是否开启跨进程通信
private ILoginInterface iLogin; // AIDL定义接口
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); // 隐藏标题
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN); // 设置全屏
setContentView(R.layout.activity_main);
initBindService();
}
// 点击事件
public void startQQLoginAction(View view) {
if (iLogin != null) {
try {
// 调用Server方法
iLogin.login();
} catch (RemoteException e) {
e.printStackTrace();
}
} else {
Toast.makeText(this, "请安装QQ应用...", Toast.LENGTH_SHORT).show();
}
}
public void initBindService() {
Intent intent = new Intent();
// 设置Server应用Action
intent.setAction("BinderB_Action");
// 设置Server应用包名(5.1+要求)
intent.setPackage("com.netease.binder.b");
// 开始绑定服务
bindService(intent, conn, BIND_AUTO_CREATE);
// 标识跨进程绑定
isStartRemote = true;
}
// 服务连接
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iLogin = ILoginInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onDestroy() {
super.onDestroy();
if (isStartRemote) {
// 解绑服务,一定要记得解绑服务,否则可能会报异常(服务连接资源异常)
unbindService(conn);
}
}
}
- 服务端注册服务
<service
android:name="com.netease.binder.client.service.MyService"
android:enabled="true"
android:exported="true"
android:process=":remote">
<intent-filter>
<!-- 激活 MyService 唯一name,不能重名-->
<action android:name="BinderA_Action" />
</intent-filter>
</service>
网友评论