这是我的问题:我在一个已经存在的使用蓝牙来获取数据且充当客户端的应用程序与我的充当服务器的应用程序之间设置了AIDL接口。 当我尝试在客户端调用方法Write时,我收到了Java NullPointerException,但这不是问题。我完全知道此异常的原因是接口的距离为null,实际上,稍后,我添加了一个if块来检查接口是否为null,以避免应用程序崩溃和该异常的返回。我知道接口为空的事实,可能是由IBinder空引起的。但是我不明白IBinder无效的原因是什么。我还尝试创建另一个不包含bluetooh代码但具有相同“连接代码”的简化应用程序Client,并将其连接到我的Server App,一切正常。
这是AIDL文件:
// PInterface.aidl
package com.example.aidl;
// Declare any non-default types here with import statements
interface PInterface {
String Write(in String data);
/**
* 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);
}
此文件在客户端和服务器中是完全相同的,即使包名是相同的。
这是客户端应用程序中的代码:
public class WorkActivity extends Activity {
//making a boolean to check connection
private boolean connection;
//declaring Intent
private Intent MyIntent;
//declaring Interface
static PInterface MyInterface;
//declaring serviceCon
static final ServiceConnection SerCon = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyInterface=PInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
MyInterface=null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_work);
//Intent
MyIntent= new Intent("spremoteservice");
//Binding remote service
connection = bindService(createExplicitFromImplicitIntent(getApplicationContext(),MyIntent),SerCon,BIND_AUTO_CREATE);
if (connection){
Log.i(TAG,"service is bounded");
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplication(),"binded",Toast.LENGTH_SHORT).show();
}
},5000);
}
else{
Log.i(TAG,"service not bounded");
Toast.makeText(getApplication(),"not binded",Toast.LENGTH_SHORT).show();
}
//trying to use the Interface method
if (MyInterface!=null) {
try {
MyInterface.Write("hello");
Log.i(TAG, "it is loading");
Toast.makeText(getApplication(),"it is loading",Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
e.printStackTrace();
}
}
public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) {
// Retrieve all services that can match the given intent
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);
// Make sure only one match was found
if (resolveInfo == null || resolveInfo.size() != 1) {
return null;
}
// Get component info and create ComponentName
ResolveInfo serviceInfo = resolveInfo.get(0);
String packageName = serviceInfo.serviceInfo.packageName;
String className = serviceInfo.serviceInfo.name;
ComponentName component = new ComponentName(packageName, className);
// Create a new intent. Use the old one for extras and such reuse
Intent explicitIntent = new Intent(implicitIntent);
// Set the component to be explicit
explicitIntent.setComponent(component);
return explicitIntent;
}
}
这是服务器应用程序的代码:
public class SpService extends Service {
public SpService() {
}
//checking if the interface method is called
//private boolean cehck=false;
//declaring reference
private int ref=0;
//declaring a Firebase Database instance
static final FirebaseDatabase mydatabase = FirebaseDatabase.getInstance();
private DatabaseReference myRef = mydatabase.getReference(""+ref);
//declaring a TAG for debugging
public static final String TAG = "hello";
//implementing the interface from AIDL file
PInterface.Stub MyInterface = new PInterface.Stub() {
@Override
public String Write(String data) throws RemoteException {
//Implementing the load method in order to send data to a real time database
myRef.setValue(data);
Log.i(TAG,"the AidlLoad method is running and ref:"+ref);
return "you done it";
}
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return MyInterface;
}
}