2015-05-11 2 views
1

У меня есть служба, которая работает в фоновом режиме и получает сообщения время от времени. Я хочу, чтобы приложения могли подключаться к моей службе и получать эти сообщения. , так что я сделал, это реализовать 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» я знаю, почему это происходит, может быть, у меня что-то есть. Я смотрел повсюду, но не мог найти ответа.

+0

Что вы делаете с cb1? – pskink

+0

@pskink Я сохраняю его до статической переменной. и когда сообщение получено, у меня есть слушатель этой переменной. Я отредактировал свой вопрос и добавил код, чтобы объяснить немного больше – yanish

ответ

0

Исходный код выглядит хорошо. Я не знаю, в чем проблема. Вы можете попробовать использовать oneway & из ключевого слова. Я пишу простую демонстрацию here, посмотрите, если хотите.

+0

Это должен быть комментарий. – rayryeng

+0

Я вижу, но у меня нет достаточной репутации для комментариев. – duynt

+0

Хорошо, если вы можете взять какой-то код из своей демонстрации и поместить его в свой ответ, который будет возможен, это было бы предпочтительнее. Ответы только на ссылки, как правило, обескуражены здесь. – rayryeng