活动和服务之间的Android通信

时间:2014-10-09 13:57:40

标签: java android android-activity android-service ipc

我尝试在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"/>

1 个答案:

答案 0 :(得分:1)

您的问题是messanger属性为null。您遇到并发问题。 bindService方法是异步的 - 它立即返回并在后台线程中执行绑定。绑定完成后,将调用onServiceConnected方法。当您尝试发送邮件时,messanger仍未初始化,因为onServiceConnected方法尚未执行。