2014-10-09 117 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