2014-10-09 75 views
0

我試圖在基於綁定信使的進程間通信的Android上實現系統服務。對於這個我下面這個教程:活動與服務之間的Android通信

http://www.survivingwithandroid.com/2014/01/android-bound-service-ipc-with-messenger.html

但不管如何我想,我不能讓它的工作。 我在網上發現了不同的教程,但最終他們都基於相同的程序。

當我嘗試與服務進行通信時,該應用程序將立即崩潰。

錯誤消息

10-09 15:40:33.490 3468-3468/com.example.stenosis.testservice E/AndroidRuntime﹕ FATAL EXCEPTION: main 
    Process: com.example.stenosis.testservice, PID: 3468 
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.stenosis.testservice/com.example.stenosis.testservice.MyActivity}: java.lang.NullPointerException 
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184) 
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233) 
      at android.app.ActivityThread.access$800(ActivityThread.java:135) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
      at android.os.Handler.dispatchMessage(Handler.java:102) 
      at android.os.Looper.loop(Looper.java:136) 
      at android.app.ActivityThread.main(ActivityThread.java:5001) 
      at java.lang.reflect.Method.invokeNative(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:515) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
      at dalvik.system.NativeStart.main(Native Method) 
    Caused by: java.lang.NullPointerException 
      at com.example.stenosis.testservice.MyActivity.sendMsg(MyActivity.java:87) 
      at com.example.stenosis.testservice.MyActivity.onCreate(MyActivity.java:49) 
      at android.app.Activity.performCreate(Activity.java:5231) 
      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148) 
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233) 
      at android.app.ActivityThread.access$800(ActivityThread.java:135) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
      at android.os.Handler.dispatchMessage(Handler.java:102) 
      at android.os.Looper.loop(Looper.java:136) 
      at android.app.ActivityThread.main(ActivityThread.java:5001) 
      at java.lang.reflect.Method.invokeNative(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:515) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
      at dalvik.system.NativeStart.main(Native Method) 

MyActivity.java:

public class MyActivity extends Activity { 

    private ServiceConnection sConn; 
    private Messenger messenger; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_my); 


     // Service Connection to handle system callbacks 
     sConn = new ServiceConnection() { 

      @Override 
      public void onServiceDisconnected(ComponentName name) { 
       messenger = null; 
      } 

      @Override 
      public void onServiceConnected(ComponentName name, IBinder service) { 
       // We are conntected to the service 
       messenger = new Messenger(service); 

      } 
     }; 

     // We bind to the service 
     bindService(new Intent(this, MyService.class), sConn, Context.BIND_AUTO_CREATE); 

     // Try to send a message to the service 
     sendMsg(); 
    } 


    // This class handles the Service response 
    class ResponseHandler extends Handler { 

     @Override 
     public void handleMessage(Message msg) { 
      int respCode = msg.what; 
      String result = ""; 

      switch (respCode) { 
       case MyService.TO_UPPER_CASE_RESPONSE: { 
        result = msg.getData().getString("respData"); 
        System.out.println("result"); 
        Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show(); 
       } 
      } 
     } 

    } 


    public void sendMsg() { 

     String val = "This is a test"; 
     Message msg = Message 
       .obtain(null, MyService.TO_UPPER_CASE); 

     msg.replyTo = new Messenger(new ResponseHandler()); 
     // We pass the value 
     Bundle b = new Bundle(); 
     b.putString("data", val); 

     msg.setData(b); 

     try { 
      messenger.send(msg); 
     } catch (RemoteException e) { 
      e.printStackTrace(); 
     } 

    } 
} 

MyService.java

public class MyService extends Service { 

    public static final int TO_UPPER_CASE = 0; 
    public static final int TO_UPPER_CASE_RESPONSE = 1; 

    private Messenger msg = new Messenger(new ConvertHanlder());; 

    @Override 
    public IBinder onBind(Intent intent) { 
     return msg.getBinder(); 
    } 

    class ConvertHanlder extends Handler { 

     @Override 
     public void handleMessage(Message msg) { 
      // This is the action 
      int msgType = msg.what; 

      switch (msgType) { 
       case TO_UPPER_CASE: { 
        try { 
         // Incoming data 
         String data = msg.getData().getString("data"); 
         Message resp = Message.obtain(null, TO_UPPER_CASE_RESPONSE); 
         Bundle bResp = new Bundle(); 
         bResp.putString("respData", data.toUpperCase()); 
         resp.setData(bResp); 

         msg.replyTo.send(resp); 
        } catch (RemoteException e) { 

         e.printStackTrace(); 
        } 
        break; 
       } 
       default: 
        super.handleMessage(msg); 
      } 
     } 
    } 
} 

AndroidManifest.xml中

<service android:name=".MyService" android:process=":convertprc"/> 
+0

你是作爲一個單元/儀器測試運行嗎? – helleye 2014-10-09 14:05:24

+0

@Tim請問您如果對您有用,並回答您的問題,請將其標記爲正確:) – 2014-10-31 08:50:38

回答

1

你的問題是,messanger屬性爲null。您遇到併發問題。 bindService方法是異步的 - 它立即返回並在後臺線程中執行綁定。綁定完成後,調用onServiceConnected方法。當您嘗試發送郵件時,messanger尚未初始化,因爲onServiceConnected方法尚未執行。

+1

是的 - 並且明確地說,您無法在onCreate()內使用服務連接。你也不能在任何其他主線程方法中將原始調用放到bindService()中。調用bindService()方法必須在平臺調用onServiceConnected()之前返回。 – 2014-10-09 16:54:04