问题描述
我正在尝试通过 AIDL 将从 Rest API 调用获得的数据传递到另一个应用程序。当我将客户端配置为进行本地调用(相同的包名称)时,它可以工作,但是当我尝试将它与另一个应用程序包名称远程使用时,它返回一个空指针异常。 如日志中所示,这两个服务有界并连接,但它仍然不起作用。我不确定我错过了什么。
更新:调试服务器端后,我知道它发送的回复错误来自 parceble 类。这是什么意思?
服务器代码:
package Aidl.Services;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.remoteexception;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.reflect.Typetoken;
import java.lang.reflect.Type;
import java.util.ArrayList;
import Aidl.Library.ResultCallback;
import Aidl.Library.ServicesInterface;
import Main.MainActivity;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class AIDLServices extends Service {
private static final String TAG = "AIDLServices";
Gson gson;
public AIDLServices() {
}
@Override
public void onCreate() {
super.onCreate();
gson = new Gson();
Log.d(TAG,"onCreate: Server Created");
}
@Override
public IBinder onBind(Intent intent) {
return sBinder;
}
private final ServicesInterface.Stub sBinder = new ServicesInterface.Stub() {
/**
* Checks services of main ambient and converts them into an jsonArray
*
* @param callback holds jsonArray of Services on callback
* @return
* @throws remoteexception
*/
@Override
public void getServices(ResultCallback callback) throws remoteexception {
callback.onResult("CinemaAPP services");
}
@Override
public void callService(String ServiceJsonString,ResultCallback callback) throws remoteexception {
callback.onResult("CinemaAPP services");
}
};
}
客户代码:
public class AidlServicesUi extends AppCompatActivity {
TextView getServices_txt;
TextView getFriends_txt;
TextView getVideo_txt;
TextView getRestaurant_txt;
private ServicesInterface ServicesInt;
private AdditionServiceConnection connection;
Gson gson;
boolean mBound;
private static final String TAG = "AidlServicesUi";
class AdditionServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name,IBinder boundservice) {
ServicesInt = ServicesInterface.Stub.asInterface((IBinder) boundservice);
Log.d(TAG,"onServiceConnected() connected");
mBound = true;
}
@Override
public void onServicedisconnected(ComponentName name) {
ServicesInt = null;
Log.d(TAG,"onServicedisconnected() disconnected");
mBound=false;
}
}
public void initService(String PackageName) {
connection = new AdditionServiceConnection();
Intent i = new Intent();
i.setClassName(PackageName,"Aidl.Services.AIDLServices");
boolean ret = bindService(i,connection,Context.BIND_AUTO_CREATE);
mBound = ret;
Log.d(TAG,"initService() bound with " + ret);
}
/**
* Unbinds this activity from the AIDL mobility service.
*/
public void releaseService() {
unbindService(connection);
connection = null;
Log.d(TAG,"releaseService() unbound.");
mBound = false;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aidl_services_ui);
getServices_txt = findViewById(R.id.txt_get_services_respone_aidl);
getFriends_txt = findViewById(R.id.txt_get_friends_services_respone_aidl);
getVideo_txt = findViewById(R.id.txt_get_video_services_respone_aidl);
getRestaurant_txt = findViewById(R.id.txt_get_restaurant_services_respone_aidl4);
gson = new Gson();
initService("com.muneeb.fypsaa.device");
}
@Override
protected void onStart() {
initService("com.muneeb.fypsaa.device");
super.onStart();
}
@Override
protected void onDestroy() {
releaseService();
super.onDestroy();
}
public void getServices(View view) throws remoteexception {
ServicesInt.getServices(new ResultCallback() {
@Override
public void onResult(String result) throws remoteexception {
MainActivity.parentServices = gson.fromJson(result,new Typetoken<ArrayList<Service>>(){}.getType());
}
@Override
public IBinder asBinder() {
return null;
}
});
}
public void FriendsService (View view) throws remoteexception {
boolean found=false;
for (int i =0;i<MainActivity.parentServices.size();i++){
Service serv = MainActivity.parentServices.get(i);
if(serv.ServiceName.equals("Friends Service")){
found=true;
String jsonFriendsService = gson.toJson(ServicesInt);
ServicesInt.callService(jsonFriendsService,new ResultCallback(){
@Override
public void onResult(String result) throws remoteexception {
Type tp = new Typetoken<ArrayList<String>>(){}.getType();
ArrayList<String> FriendsOnline = gson.fromJson(result,tp);
getFriends_txt.setText(FriendsOnline.toString());
}
@Override
public IBinder asBinder() {
return null;
}
});
}
}
if (found==false){
getFriends_txt.setText("Service is not availible right Now");
}
}
public void VideoService (View view) throws remoteexception {
boolean found=false;
for (int i =0;i<MainActivity.parentServices.size();i++){
Service serv = MainActivity.parentServices.get(i);
if(serv.ServiceName.equals("Video Streaming Service")){
found=true;
String jsonFriendsService = gson.toJson(ServicesInt);
ServicesInt.callService(jsonFriendsService,tp);
getFriends_txt.setText(FriendsOnline.toString());
}
@Override
public IBinder asBinder() {
return null;
}
});
}
}
if (found==false){
getVideo_txt.setText("Service is not availible right Now");
}
}
public void RestaurantService (View view) throws remoteexception {
boolean found=false;
for (int i =0;i<MainActivity.parentServices.size();i++){
Service serv = MainActivity.parentServices.get(i);
if(serv.ServiceName.equals("Restaurant Service")){
found=true;
String jsonFriendsService = gson.toJson(ServicesInt);
ServicesInt.callService(jsonFriendsService,tp);
getFriends_txt.setText(FriendsOnline.toString());
}
@Override
public IBinder asBinder() {
return null;
}
});
}
}
if (found==false){
getRestaurant_txt.setText("Service is not availible right Now");
}
}
}
AIDL 服务接口
import Aidl.Library.ResultCallback;
// Declare any non-default types here with import statements
interface ServicesInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void getServices(ResultCallback callback);
void callService(String ServiceJsonString,ResultCallback callback);
}
AIDL 结果回调接口
interface ResultCallback {
void onResult(String result);
}
错误日志
D/AidlmobilityUi: initService() bound with true
D/AidlmobilityUi: initService() bound with true
D/AidlmobilityUi: onServiceConnected() connected
D/AidlmobilityUi: onServiceConnected() connected
D/EGL_emulation: eglMakeCurrent: 0xec285360: ver 2 0 (tinfo 0xec283330)
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.muneeb.fypsaa.cinema,PID: 3116
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:390)
at android.view.View.performClick(View.java:6597)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:6597)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void Aidl.Library.ResultCallback.onResult(java.lang.String)' on a null object reference
at android.os.Parcel.createException(Parcel.java:1948)
at android.os.Parcel.readException(Parcel.java:1910)
at android.os.Parcel.readException(Parcel.java:1860)
at Aidl.Library.mobilityInterface$Stub$Proxy.getSiblings(mobilityInterface.java:176)
at Main.AidlmobilityUi.SendgetSiblingsRequest(AidlmobilityUi.java:130)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:385)
at android.view.View.performClick(View.java:6597)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)