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

+0

@ Возможно, я попрошу вас пометить ответ как правильный, если он вам будет полезен и ответит на ваш вопрос :) –

ответ

1

Ваша проблема в том, что messanger свойство равно нулю. Вы столкнулись с проблемой параллелизма. Метод bindService является асинхронным - он немедленно возвращается и выполняет привязку в фоновом потоке. Когда привязка завершена, вызывается метод onServiceConnected. Когда вы пытаетесь отправить сообщение, messanger все еще не инициализирован, так как метод onServiceConnected еще не выполнен.

+1

Да - и, чтобы выразить его в практических условиях, вы не можете использовать сервисное соединение внутри onCreate(). Также вы не можете использовать его в любом другом методе основного потока, который ставит исходный вызов bindService(). Метод, вызывающий bindService(), должен вернуться до того, как платформа может вызвать onServiceConnected(). –

Смежные вопросы