2015-05-11 60 views
1

我有一個服務,在後臺工作,並且每隔一段時間接收消息。 我希望應用能夠連接到我的服務並接收這些消息。 所以我做的是使用AIDL實現IPC。我已經創建了兩個AIDL文件: 「IExtMessage」:AIDL ipc messaging caused 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); 
} 

,並創建了一個會收到這些形式交往,以測試這個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) 

我不不知道爲什麼會發生,也許我在某處或某處發生了泄漏。 我看到處處都找不到答案。

+0

你在用cb1做什麼? – pskink

+0

@pskink我將它保存到一個靜態變量。當收到消息時,我有一個關於該變量的監聽器。 我編輯了我的問題,並添加了代碼來解釋更多 – yanish

回答

0

您的源代碼看起來不錯。我真的不知道什麼是問題。你可以嘗試單向使用& out關鍵字。我寫了一個簡單的演示here,看看你是否想要。

+0

這應該是一個評論。 – rayryeng

+0

我明白了,但我並沒有足夠的評論聲望。 – duynt

+0

好吧,如果你可以從演示中獲取一些代碼並將其放入可運行的答案中,那將是更可取的。在這裏,僅有鏈接的答案往往會受到阻礙。 – rayryeng