Android高级进阶

2019-08-13-Android进程通信方式总结

2019-08-14  本文已影响0人  王元

首先,我们可以想一些通信的方式,

大部分通信基于以上俩种方式来实现的,接下来我们看下Android
为我们提供的进程通信方式有哪些

一,广播

通过系统AMS的机制实现多进程通信

二,ContentProvider

通过共享内容的方式

三,共享文件

并发不多或者无并发的情况可以使用

四,Socket

服务端建立severSocket,客户端建立连接,实现相互通信。socket常用于网络通信

五,使用Bundle的方式

利用Bundle进行进程间通信是很容易的,大家应该注意到,这种方式进行进程间通信只能是单方向的简单数据传输,它使用时有一定的局限性。

六,Messenger(信息员)

消息是单向的,使用的是handler来实现,因此并发的效率不高,适合消息较少的情况下使用

1,消息的发送方:

public class ClientActivity extends AppCompatActivity {
    private Messenger mPutMessage;
    private final WeakHandler mClientHandler = new WeakHandler(msg -> {
        try {
//            msg.replyTo = new Messenger()
            if(mPutMessage != null)mPutMessage.send(msg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    });

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent i = new Intent(this, MessagerService.class);
        bindService(i, conn, Service.BIND_AUTO_CREATE);

        Button btn = new Button(this);
        setContentView(btn);
        btn.setText("send");
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Message pool = Message.obtain();
                pool.what = 1;
                Bundle bundle = new Bundle();
                bundle.putString("key", "test messager");
                pool.obj = bundle;
                mClientHandler.sendMessage(pool);
            }
        });

    }

    private final ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mPutMessage = new Messenger(iBinder);
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mPutMessage = null;
        }
    };


    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(conn);
    }
}

2,消息的接收方

public class MessagerService extends Service {

    private final WeakHandler mServiceHandler = new WeakHandler(msg -> {
        switch (msg.what) {
            case 1:
                Log.e("MessagerService", "服务端收到客户端的消息=" + msg.obj);

                Bundle b = (Bundle) msg.obj;
                Toast.makeText(getApplicationContext(), "服务端收到客户端的消息=" + b.getString("key"), Toast.LENGTH_LONG).show();
                break;

            default:
                break;
        }
    });

    private Messenger messenger;

    @Override
    public void onCreate() {
        super.onCreate();
        messenger = new Messenger(mServiceHandler);
    }

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

注意:这种方式的消息不仅是单向的,而且发送的所有消息类型必须是实现Parcelable序列化的,否则会 Can't marshal non-Parcelable objects across processes.异常

七,AIDL

Android系统内的大部分进程通信都是基于AIDL来实现的

1,创建进程通信桥梁-AIDl文件

MediaInfo.aidl

package com.aidl.data;

// Declare any non-default types here with import statements

parcelable MediaInfo;

IMeidia.aidl

package com.aidl;

import com.aidl.data.MediaInfo;
// Declare any non-default types here with import statements

interface IMeidia {
    MediaInfo getMeidiaInfo();
    void playMedia(String url);
    void stopMedia();
}

2,声明进程通信访问对象

public class MediaInfo implements Parcelable {
    public int mediaId;
    public String mediaName;
    public String url;
        
    public MediaInfo(int mediaId, String mediaName, String url) {
        this.mediaId = mediaId;
        this.mediaName = mediaName;
        this.url = url;
    }
        
    protected MediaInfo(Parcel in) {
        mediaId = in.readInt();
        mediaName = in.readString();
    }
        
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mediaId);
        dest.writeString(mediaName);
    }
        
        
        
    @Override
    public int describeContents() {
        return 0;
    }
        
    public static final Creator<MediaInfo> CREATOR = new Creator<MediaInfo>() {
        @Override
        public MediaInfo createFromParcel(Parcel in) {
            return new MediaInfo(in);
        }
        
        @Override
        public MediaInfo[] newArray(int size) {
            return new MediaInfo[size];
        }
    };
        
    @Override
    public String toString() {
        return "MediaInfo{" +
                "mediaId=" + mediaId +
                ", mediaName='" + mediaName + '\'' +
                '}';
    }
}

2,建立服务端

/**
 * 进程通信服务端
 */
public class MediaService extends Service {

    public static final String ACTION = "service.com.aidl.MediaService";

    private final com.aidl.IMeidia.Stub mBinder = new com.aidl.IMeidia.Stub() {
        @Override
        public MediaInfo getMeidiaInfo() throws RemoteException {
            return new MediaInfo(10001, MediaService.class.getSimpleName(), "");
        }

        @Override
        public void playMedia(String url) throws RemoteException {
            startPlayer(url);
        }

        @Override
        public void stopMedia() throws RemoteException {
            stopMPlayer();
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

2,客户端绑定server,获取消息或者发送消息

public class AidlClientActivity extends Activity {

    private com.aidl.IMeidia mMedia;
    
    private final ServiceConnection mConn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mMedia = com.aidl.IMeidia.Stub.asInterface(service);
            try {
                //获取消息
                mMedia.getMeidiaInfo();
                //发送消息
                mMedia.playMedia("url");
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void onServiceDisconnected(ComponentName name) {
            try {
                mMedia.stopMedia();
                mMedia = null;
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent i = new Intent(this, MediaService.class);
        bindService(i, mConn, Context.BIND_AUTO_CREATE);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mConn);
    }
}
上一篇下一篇

猜你喜欢

热点阅读