java - AIDL 客户端未绑定到远程服务
问题描述
我正在尝试使用远程服务运行简单的乘法。我有 AIDL 服务器文件声明和定义方法。在 AIDL 中,我在服务器的包名称下复制了与服务器相同的 AIDL 文件。我已经给出了服务器服务的意图过滤器的操作。我的 AIDL 客户端代码仍然没有连接到服务。
AIDL服务器:
显现
<service
android:name=".CalService"
android:enabled="true"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="mutliply"/>
</intent-filter>
</service>
ICalService.aidl
interface ICalService {
String getMessage(String name);
int getResult(int val1, int val2);
}
CalService.java
public class CalService extends Service {
public CalService() {
}
private final ICalService.Stub binder = new ICalService.Stub() {
@Override
public String getMessage(String name) throws RemoteException {
return "Hello " + name + ". The result is: ";
}
@Override
public int getResult(int val1, int val2) throws RemoteException {
return val1 * val2;
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
}
AIDLC客户端:
MainActivity.java
@Override
protected void onStart() {
super.onStart();
editName = (EditText) findViewById(R.id.editName);
editVal1 = (EditText) findViewById(R.id.editVal1);
editVal2 = (EditText) findViewById(R.id.editVal2);
resultView = (TextView) findViewById(R.id.resultView);
if(calService == null) {
Log.v("CALSERVICE", "cal service null");
Intent it = new Intent("multiply");
it.setPackage("com.example.aidlserver");
if(getBaseContext().getApplicationContext().bindService(
it, connection, Context.BIND_AUTO_CREATE
) == true){
Log.v("Bind", "Bind service Succeeded");
} else {
Log.v("Bind", "Bind service failed");
}
} else {
Log.v("Cal", "Cal Service not null");
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(connection);
}
public void mutiply(View v) {
switch (v.getId()) {
case R.id.btnCal:
int num1 = Integer.parseInt(editVal1.getText().toString());
int num2 = Integer.parseInt(editVal2.getText().toString());
try {
int result = calService.getResult(num1, num2);
String msg = calService.getMessage(editName.getText().toString());
resultView.setText(msg + result);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
}
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("onServiceConnected", "Connected");
calService = ICalService.Stub.asInterface(service);
Toast.makeText(getApplicationContext(), "Service Connected",
Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d("onServiceDisconnected", "Disconnected");
calService = null;
Toast.makeText(getApplicationContext(), "Service Disconnected",
Toast.LENGTH_SHORT).show();
}
};
解决方案
该代码显示了它在调用 bindService 时使用的隐式意图。
Intent it = new Intent("multiply");
it.setPackage("com.example.aidlserver");
如果您的 API 级别高于 21,则必须以明确的意图更新您的代码。请使用 setClassName() API 更新您的代码,以便以明确的意图进行绑定服务调用。
Intent it = new Intent("multiply");
it.setClassName("com.example.aidlserver","com.example.aidlserver.CalService");
if(getBaseContext().getApplicationContext().bindService(it, connection, Context.BIND_AUTO_CREATE) == true){
Log.v("Bind", "Bind service Succeeded");
} else {
Log.v("Bind", "Bind service failed");
}
请注意以下事项:
注意:为确保您的应用程序安全,请始终在启动服务时使用显式意图,并且不要为您的服务声明意图过滤器。使用隐式意图启动服务是一种安全隐患,因为您无法确定响应该意图的服务,并且用户无法看到哪个服务启动。从 Android 5.0(API 级别 21)开始,如果您使用隐式 Intent 调用 bindService(),系统将引发异常。参考:https ://developer.android.com/guide/components/services
也检查一下,
“要接收隐式意图,您必须在意图过滤器中包含 CATEGORY_DEFAULT 类别”
<category android:name="android.intent.category.DEFAULT"/>
https://developer.android.com/guide/components/intents-filters#Receiving
推荐阅读
- android - 使用 Firebase Cloud Firestore 将数据添加到文档
- laravel - 登录时生成的 Laravel Passport 新访问令牌
- eloqua - Eloqua's update event API endpoint overwrites instead of updating
- java - 如果步骤失败,则 Spring Batch 退出作业
- swift - 如果字典类型是 [String: Any],我能否获得特定值的值?
- common-lisp - 如何将 common-lisp' 局部变量传递给最大值?
- python - 在opencv python中创建一个掩码并删除内部轮廓
- linux - linux maven vs mac maven
- uipickerview - 在 Swift 4 中设置 UIPickerView 位置
- java - 与 Java 或其他非函数式语言相比,Scala 究竟如何利用更多内核?