• Bundle
  • File sharing
  • ContentProvider
  • Socket
  • Messenger
  • AIDL

Bundle

Let’s look at the dialing code first

Uri uri = Uri.parse("smsto:10086");
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
Bundle bundle = new Bundle();
bundle.putString("sms_body"."SMS Text");
intent.putExtras(bundle);
//  intent.putExtra("sms_body"."SMS Text");
startActivity(intent);
Copy the code

As you can see, by storing the data in the Intent’s Bundle, you can transfer data between different processes/apps.

File sharing

By writing data to a file, different processes can read and access the file to achieve cross-process communication. However, when multiple processes access a file at the same time, concurrency and IO performance may be low.

ContentProvider

One of the four components of Android that provide a unified format for accessing data. Data sources can be files, databases. Can provide external access interface, realize cross-process /APP access.

private void readContacts() {/ / used to query the Phone number of a URI URI phoneUri = ContactsContract.Com monDataKinds. Phone. CONTENT_URI; / / field of query String [] the projection = {ContactsContract.Com monDataKinds. Phone. DISPLAY_NAME, / / directory name ContactsContract.CommonDataKinds.Phone.DATA1,"sort_key",// Address book mobile phone number}; Cursor cursor = getContentResolver().query(phoneUri, projection, null, null, null);while((cursor.moveToNext())) { String name = cursor.getString(0); String phone = cursor.getString(1); }}Copy the code

Socket

There are two main types of sockets

  • StreamSocket: Tcp-based encapsulation that provides data exchange services in the form of streams. It provides stable bidirectional communication and establishes connections through the “three-way handshake” to ensure high data transmission stability. In Java, the client uses the Socket class and the server uses the ServerSocket class.
  • DatagramSocket: Encapsulates the UDP protocol and provides data exchange services in the form of data packets, providing unstable unidirectional communication and higher execution efficiency. Because the connectionless mode is used, data transmission is unstable and data integrity is not guaranteed. Java uses DatagramPacket class, represents the data packet; DatagramSocket class for end-to-end communication.

Messager

The underlying layer is also implemented by encapsulating AIDL, so it is used in much the same way as AIDL.

  1. Create a Messenger object in the server process Service, which is used to receive Message data from the client, obtain the client Messenger object, and send Message data to the client.
  2. Create a client Messenger object to receive server data.
  3. The client binds the server service and obtains the server Messenger object, which is used to send Message data to the server.
  4. Add the client Messenger object to message.replyto by sending a Message through the server Messenger.
public class MsgerService extends Service {
    private Messenger mServerMessenger = new Messenger(new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); Switch (msg.what) {case 1000:

                    Toast.makeText(getBaseContext(), "" + msg.arg1, Toast.LENGTH_SHORT).show();

                    Message cMsg = Message.obtain();
                    cMsg.what = msg.what;
                    Bundle bundle = new Bundle();
                    bundle.putString("name"."Jim"); cMsg.obj = bundle; CMsger = msg.replyTo; cMsger = msg.replyTo; Try {// Send a message to the client cmsger. send(cMsg); } catch (RemoteException e) { e.printStackTrace(); }break; }}}); @Nullable @Override public IBinder onBind(Intent intent) {returnmServerMessenger.getBinder(); }}Copy the code
public class ClientActivity extends Activity { private TextView mNameTxt; Private Messenger mClientMessenger = new Messenger(newHandler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case1000: // Receive server data Bundle = (Bundle) msg.obj; mNameTxt.setText(bundle.getString("name"));
                    break; }}}); Private Messenger mServerMessenger; /** * Private Messenger mServerMessenger; private ServiceConnection mConnection = newServiceConnection() { @Override public void onServiceConnected(ComponentName name, MServerMessenger = new Messenger(service); } @Override public void onServiceDisconnected(ComponentName name) { mServerMessenger = null; }}; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState);setContentView(R.layout.fragment_common); mNameTxt = (TextView) findViewById(R.id.name); Intent = new Intent(this, msgerservice.class);bindService(intent, mConnection, BIND_AUTO_CREATE);

        findViewById(R.id.bind).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int number = (int) (Math.random() * 100); Message msg = Message.obtain(); msg.what = 1000; msg.arg1 = number; msg.replyTo = mClientMessenger; // Send a message to the serverif(mServerMessenger ! = null) { try { mServerMessenger.send(msg); } catch (RemoteException e) { e.printStackTrace(); }}}}); }}Copy the code

AIDL

Android Interface Definition Language (AIDL) is an Interface Definition Language that enables clients and servers to communicate with each other using a common recognized programming Interface between processes. AIDL uses a relatively large number of steps, which can be summarized as three basic steps:

  • Create an AIDL interface

  • Create a remote Service Service based on AIDL

  • Bind the remote Service

(1) Create the AIDL interface

Define the AIDL interface file

This File is already integrated in Android Studio. Right click on the project, go to New -> AIDL -> AIDL File, and enter the name of the interface. This will create a Java level in the SRC /main directory. The package name is the same as the package name in the Java directory, and the extension is. Aidl

// Declare any non-default types here with import statements interface IMyAidlTest { /** * Demonstrates some basic types  that you can use as parameters * andreturn values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
}
Copy the code

The above file is a template file automatically created by Android Studio. The basicTypes method in it is not needed and can be deleted. AIDL’s support for data types includes all the basic data types in Java, as well as String, CharSequence, List, and Map.

Customize the data type of AIDL

For example, if we have a Product class that needs to pass data, then this class must implement the Parcelable interface and declare it in a new AIDL file with the same class name. And the path of the AIdl file must be the same as the entity classpath in the Java file, such as product.aidl

package demo.csdn.zhuwentao.bean;

parcelable Product;
Copy the code

Use import in imyaidltest. aidl to import all custom data types except those supported by aiDL by default. The package name and path must be exact to the class name.

interface IMyAidlTest {
    void addProduct(in Product person);
    List<Product> getProductList();
}
Copy the code

The methods here serve only as interface declarations. The interface defined above will eventually implement the specific operation logic in the Service.

Generate Java interface files from aiDL files

Android Studio has already integrated this step for us. Just click on Build -> Make Project, or click on the little hammer icon on AS. After the build is automatically according to our definition of IMyAidlTest. IMyAidlTest aidl file. Java interface classes, can be in the build/generated/source/aidl/debug/directory to find the class.

(2) Create a remote Service from AIDL

The imyaidltest. Java interface file created in the previous step needs to use Service to bind, so we need to create a new Service Service.

Public class MyAidlService extends Service {private List<Product> mProducts; publicMyAidlService() {
    }

    private IBinder mIBinder = new IMyAidlTest.Stub() {

        @Override
        public void addProduct(Product product) throws RemoteException {
            mProducts.add(product);
        }

        @Override
        public List<Product> getProductList() throws RemoteException {
            returnmProducts; }}; @Nullable @Override public IBinder onBind(Intent intent) { mProducts = new ArrayList<>();returnmIBinder; }}Copy the code

The mIBinder object instantiates imyaidltest.stub and implements the final processing logic in the callback interface. Binding to the client triggers the onBind() method and returns a Binder object for the client to use. The client can use this class to invoke the interface methods implemented in the service by adding a declaration to the configuration file and specifying it to run in a new process using the Android: Process attribute.

<service
    android:name=".MyAidlService"
    android:process=":process"/>
Copy the code

After the above steps are configured, the server side for cross-process communication is configured

(3) Bind the remote Service

Once the cross-process communication server is implemented, you can start invoking it in the client by first creating the service connection object in the Activity

private IMyAidlTest mAidlTest;

private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mAidlTest = IMyAidlTest.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { mAidlTest = null; }};Copy the code

The connection is then established by binding the Service to the Intent’s bindService

Intent intent = new Intent(getApplicationContext(), MyAidlService.class);
bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
Copy the code

Once started, the onServiceConnected method will be called back at connection time, and the callback will generate an interface that implements the mAidlTest object, which is the object that we called the cross-process operation, and then the AIDL method will be operated on through this mAidlTest object.

private void addProduct(String name, int price) { Product pro = new Product(); pro.mName = name; pro.mPrice = price; Try {// Call AIDL method mAidlTest maidltest.addProduct (pro); List<Product> proLists = mAidlTest.getProductList(); mAIDLTv.setText(proLists.toString()); } catch (RemoteException e) { e.printStackTrace(); }}Copy the code

These are the basic steps that AIDL uses.

Reference: www.jianshu.com/p/b17f1276e…