У меня есть служба, которая работает в фоновом режиме и получает сообщения время от времени. Я хочу, чтобы приложения могли подключаться к моей службе и получать эти сообщения. , так что я сделал, это реализовать IPC с помощью AIDL. Я создал два AIDL файлы: "IExtMessage":AIDL ipc messaging вызывает nullpointerexception
package com.tfl.extprotocolservice;
import com.tfl.extprotocolservice.ICallBackMessage;
interface IExtMessage{
void getMessage(ICallBackMessage cb);
}
и "ICallBackMessage":
package com.tfl.extprotocolservice;
interface ICallBackMessage{
void onMessageReceived(int parameter,int state);
}
и создали приложение, которое будет получать эти messsages, чтобы проверить эту IPC:
public class MainActivity extends Activity implements ServiceConnection{
private IExtMessage binding=null;
private parseParametersTask task=null;
HashMap<Integer,List<String>> parameters;
ParameterAlert alert;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connectToService();
task=new parseParametersTask();
task.execute();
parameters=ReadParams.params;
}
public void connectToService(){
Intent implicit=new Intent(IExtMessage.class.getName());
List<ResolveInfo> matches=getPackageManager().queryIntentServices(implicit, 0);
if(matches.size()==0){
Toast.makeText(getApplicationContext(), "Cannot find a matching service!", Toast.LENGTH_LONG).show();
}
else if (matches.size()>1){
Toast.makeText(getApplicationContext(), "Found multiple matching services!", Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(getApplicationContext(), "Found the Protocol Service", Toast.LENGTH_LONG).show();
Intent explicit=new Intent(implicit);
ServiceInfo svcInfo=matches.get(0).serviceInfo;
ComponentName cn=new ComponentName(svcInfo.applicationInfo.packageName, svcInfo.name);
explicit.setComponent(cn);
bindService(explicit, this, Context.BIND_AUTO_CREATE);
}
}
public void buttonClick(View v) {
if (v.getId() == R.id.navigation) {
DialogFragment dialog = new navigationChooserFragment();
dialog.show(getFragmentManager(), "navigation");
}
if(v.getId()==R.id.ptt){
PackageManager pm=getPackageManager();
Intent i=pm.getLaunchIntentForPackage("com.loudtalks");
i.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(i);
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("SERVICE", "Service Connected");
binding=IExtMessage.Stub.asInterface(service);
try {
binding.getMessage(cb);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d("SERVICE","Service disconnected :(");
binding=null;
}
ICallBackMessage.Stub cb=new ICallBackMessage.Stub() {
@Override
public void onMessageReceived(int parameter,int state) throws RemoteException {
Log.d("SERVICE","received parameter "+parameter);
Log.d("SERVICE", "received state " + state);
FragmentManager fm=getFragmentManager();
FragmentTransaction ft=fm.beginTransaction();
if(state==1){
alert=new ParameterAlert();
Bundle bundleParam=new Bundle();
bundleParam.putInt("parameter",parameter);
alert.setArguments(bundleParam);
alert.show(ft,"alert");
}else {
if (alert.isVisible()) {
alert.dismiss();
}
}
}
};
class parseParametersTask extends AsyncTask<Void,Void,Void>{
@Override
protected Void doInBackground(Void... params) {
ReadParams readParams =new ReadParams();
try {
readParams.setInputFile(getAssets().open("parameters.xls"));
readParams.read();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
это - соответствующий код от моей службы:
public IBinder onBind(Intent intent) {
return (new ExtMessageBinder());
}
private static class ExtMessageBinder extends IExtMessage.Stub {
@Override
public void getMessage(ICallBackMessage cb) throws RemoteException {
L.m("TESTSERVICE","getMessage in Service called");
cb1 = cb;
}
}
cb1 - статическая переменная ICallBackMessage, которую я сохраняю при получении сообщения. и в моей службе, это слушатель, который передает сообщения:
try {
cb1.onMessageReceived(carParameter, state);
} catch (RemoteException e1) {
// TODO Auto-generated catch block
L.m("TESTSERVICE", "" + e1);
}
так, проблема, иногда все работает отлично, но иногда мои службы падают с этим исключением:
05-11 13:55:28.763: E/AndroidRuntime(1924): FATAL EXCEPTION: main
05-11 13:55:28.763: E/AndroidRuntime(1924): java.lang.NullPointerException
05-11 13:55:28.763: E/AndroidRuntime(1924): at android.os.Parcel.readException(Parcel.java:1333)
05-11 13:55:28.763: E/AndroidRuntime(1924): at android.os.Parcel.readException(Parcel.java:1281)
05-11 13:55:28.763: E/AndroidRuntime(1924): at com.tfl.extprotocolservice.ICallBackMessage$Stub$Proxy.onMessageReceived(ICallBackMessage.java:83)
05-11 13:55:28.763: E/AndroidRuntime(1924): at com.tfl.extprotocolservice.ExtProtocolService$1.handleMessage(ExtProtocolService.java:127)
05-11 13:55:28.763: E/AndroidRuntime(1924): at android.os.Handler.dispatchMessage(Handler.java:99)
05-11 13:55:28.763: E/AndroidRuntime(1924): at android.os.Looper.loop(Looper.java:137)
05-11 13:55:28.763: E/AndroidRuntime(1924): at android.app.ActivityThread.main(ActivityThread.java:4424)
05-11 13:55:28.763: E/AndroidRuntime(1924): at java.lang.reflect.Method.invokeNative(Native Method)
05-11 13:55:28.763: E/AndroidRuntime(1924): at java.lang.reflect.Method.invoke(Method.java:511)
05-11 13:55:28.763: E/AndroidRuntime(1924): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-11 13:55:28.763: E/AndroidRuntime(1924): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-11 13:55:28.763: E/AndroidRuntime(1924): at dalvik.system.NativeStart.main(Native Method)
Я DON» я знаю, почему это происходит, может быть, у меня что-то есть. Я смотрел повсюду, но не мог найти ответа.
Что вы делаете с cb1? – pskink
@pskink Я сохраняю его до статической переменной. и когда сообщение получено, у меня есть слушатель этой переменной. Я отредактировал свой вопрос и добавил код, чтобы объяснить немного больше – yanish