美文网首页
【Android】一种简单方法跨进程访问另一个app的Servi

【Android】一种简单方法跨进程访问另一个app的Servi

作者: 李翾 | 来源:发表于2018-01-15 17:24 被阅读0次

    先看代码另一个App的Service写法:

    public class MyService extends Service {
    
        static String TAG = "远程服务端";
        /**
         * Holds last value set by a client.
         */
        int mValue = 0;
        /**
         * Command to the service to register a client, receiving callbacks
         * from the service.  The Message's replyTo field must be a Messenger of
         * the client where callbacks should be sent.
         */
        static final int MSG_REGISTER_CLIENT = 1;
    
        /**
         * Command to the service to unregister a client, ot stop receiving callbacks
         * from the service.  The Message's replyTo field must be a Messenger of
         * the client as previously given with MSG_REGISTER_CLIENT.
         */
        static final int MSG_UNREGISTER_CLIENT = 2;
    
        /**
         * Command to service to set a new value.  This can be sent to the
         * service to supply a new value, and will be sent by the service to
         * any registered clients with the new value.
         */
        static final int MSG_SET_VALUE = 3;
        /**
         * Target we publish for clients to send messages to IncomingHandler.
         */
        final Messenger mMessenger = new Messenger(new IncomingHandler());
    
    
        public MyService() {
        }
    
        ArrayList<Messenger> mClients = new ArrayList<>();
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
    
            Log.i(TAG, "远程服务onBind");
            return mMessenger.getBinder();
        }
    
        /**
         * Handler of incoming messages from clients.
         */
        class IncomingHandler extends Handler {
            @Override
            public void handleMessage(Message msg) {
                Log.i(TAG, "IncomingHandler收到消息" + msg.what + "");
                switch (msg.what) {
                    case MSG_REGISTER_CLIENT:
                        mClients.add(msg.replyTo);
                        break;
                    case MSG_UNREGISTER_CLIENT:
                        mClients.remove(msg.replyTo);
                        break;
                    case MSG_SET_VALUE:
                        mValue = msg.arg1;
                        mValue++;
                        Log.d(TAG, " mValue=%d" + mValue + "");
                        for (int i = mClients.size() - 1; i >= 0; i--) {
                            try {
                                mClients.get(i).send(Message.obtain(null,
                                        MSG_SET_VALUE, mValue, 0));
                            } catch (RemoteException e) {
                                // The client is dead.  Remove it from the list;
                                // we are going through the list from back to front
                                // so this is safe to do inside the loop.
                                Log.i(TAG, msg.what + "IncomingHandler异常了RemoteException");
                                mClients.remove(i);
                            }
                        }
                        break;
                    default:
                        super.handleMessage(msg);
                }
            }
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            Log.i(TAG, "服务端创建了onCreate");
        }
    }
    

    关键代码:

     @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
    
            Log.i(TAG, "远程服务onBind");
            return mMessenger.getBinder();
        }
    

    我们在onBind返回了一个Messenger,因为Messenger实现了AIDL.再看客户端app如何写:

    public class InnerActivityTest {
    
    
        public static class InnerActivity extends AppCompatActivity {
            static String TAG = "客户端";
            /**
             * Messenger for communicating with service.
             */
            Messenger mService = null;
            int i;
            int msgArg1 = 10;
            boolean isSuccess;
            long forStartTime;
            long forEndTime;
            long startTime;
            long endTime;
            private TextView textView;
            /**
             * Target we publish for clients to send messages to IncomingHandler.
             */
            final Messenger mMessenger = new Messenger(new IncomingHandler());
    
            /**
             * Class for interacting with the main interface of the service.
             */
            private ServiceConnection mConnection = new ServiceConnection() {
                public void onServiceConnected(ComponentName className,
                                               IBinder service) {
                    // This is called when the connection with the service has been
                    // established, giving us the service object we can use to
                    // interact with the service.  We are communicating with our
                    // service through an IDL interface, so get a client-side
                    // representation of that from the raw service object.
                    mService = new Messenger(service);
    
                    isSuccess = true;
                    // We want to monitor the service for as long as we are
                    // connected to it.  v
                    try {
                        Message msg = Message.obtain(null,
                                1);
                        msg.replyTo = mMessenger;
    
                        mService.send(msg);
    
                        // Give it some value as an example.
                        msg = Message.obtain(null,
                                3, msgArg1, 0);
                        mService.send(msg);
                    } catch (RemoteException e) {
                        // In this case the service has crashed before we could even
                        // do anything with it; we can count on soon being
                        // disconnected (and then reconnected if it can be restarted)
                        // so there is no need to do anything here.
    
                        Log.i(TAG, "客户端连接服务器异常了");
                    }
    
                    // As part of the sample, tell the user what happened.
    //                Toast.makeText(InnerActivity.this,"RemoteException",
    //                        Toast.LENGTH_SHORT).show();
                }
    
                public void onServiceDisconnected(ComponentName className) {
                    // This is called when the connection with the service has been
                    // unexpectedly disconnected -- that is, its process crashed.
                    mService = null;
    
                    // As part of the sample, tell the user what happened.
                    Toast.makeText(InnerActivity.this, "onServiceDisconnected",
                            Toast.LENGTH_SHORT).show();
                }
            };
    
            /**
             * Handler of incoming messages from service.
             */
            class IncomingHandler extends Handler {
                @Override
                public void handleMessage(Message msg) {
                    switch (msg.what) {
                        case 3:
    
                            msgArg1 = msg.arg1;
                            textView.setText("显示服务端返回的数据:" + msgArg1);
    
    
                        default:
                            super.handleMessage(msg);
                    }
                }
            }
    
            @Override
            protected void onCreate(@Nullable Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
    
    
                textView = new TextView(this);
                textView.setText("显示服务端返回的数据:");
                textView.setTextColor(getResources().getColor(R.color.black));
                Button button = new Button(this);
                button.setText("往远程服务发信息");
                button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (isSuccess) {
    
    
                            Message msg = Message.obtain();
                            msg.replyTo = mMessenger;
                            msg.arg1 = msgArg1;
                            msg.what = 3;
                            try {
                                mService.send(msg);
                            } catch (RemoteException e) {
                                e.printStackTrace();
                            }
                        } else {
    
                            bindService(new Intent().setComponent(new ComponentName("com.martin.matrix", "com.martin.matrix.MyService")), mConnection, Context.BIND_AUTO_CREATE);
    
                        }
                    }
                });
                LinearLayout linearLayout = new LinearLayout(this);
                linearLayout.setOrientation(LinearLayout.VERTICAL);
                linearLayout.addView(button);
                linearLayout.addView(textView);
                setContentView(linearLayout);
    
    
            }
    }
    

    看关键代码:

    我们在客户端app里面也维护了一个Messenger, final Messenger mMessenger = new Messenger(new IncomingHandler());
    发送消息就利用服务端onBind返回的Messenger,如图所示:

    service.png

    调用Messenger的send方法,即可在维护handler里面拿到数据。
    是不是很简单,这段示例代码就是ApiDemos里面所示。

    相关文章

      网友评论

          本文标题:【Android】一种简单方法跨进程访问另一个app的Servi

          本文链接:https://www.haomeiwen.com/subject/qhedoxtx.html