Android10.0 Binder communication theory (IX) -AIDL Binder Example

Summary: This section Android10.0 Binder to explain how to use AIDL

Read this article takes approximately 20 minutes.

Articles starting micro-channel public number: IngresGe

Focus on Android system-level source code analysis, the Android platform design, welcome attention to me, thank you!

[Learn the way the Android] are based on source Android-Q (10.0) were analyzed

[Android learn the way] series:

"Boot articles"

  1. Android System Architecture
  2. Android is how to start
  3. Android 10.0 system starts the init process
  4. Android10.0 system startup process of Zygote
  5. Android 10.0 system startup process of SystemServer
  6. Android 10.0 System Services of ActivityMnagerService
  7. Android10.0 system starts the Launcher (Desktop) to start the process
  8. Android10.0 application process as well as the creation of Zygote fork process
  9. Android 10.0 PackageManagerService (a) works and start the process
  10. Android 10.0 PackageManagerService (ii) allowed to scan
  11. Android 10.0 PackageManagerService (three) scanning APK
  12. Android 10.0 PackageManagerService (four) installation process APK

"Log System chapter"

  1. Android10.0 log analysis system (a) -logd, logcat instruction description, classification and properties
  2. Android10.0 log analysis system (b) -logd, logcat architecture analysis and log system initialization
  3. Android10.0 log analysis system (C) -logd, logcat log write source code analysis
  4. Android10.0 logging system analysis (four) -selinux, kernel log in to achieve in logd

"Binder communication principle" :

  1. Android10.0 Binder communication principle (one) Binder, HwBinder, VndBinder Overview
  2. Android10.0 Binder communication theory (b) -Binder Beginners
  3. Android10.0 Binder communication theory (c) -ServiceManager articles
  4. Android10.0 Binder communication theory (four) -Native-C C ++ case study \
  5. Android10.0 Binder communication theory (five) -Binder Driving
  6. How Android10.0 Binder communication theory (six) -Binder complete data directed against
  7. Android10.0 Binder communication theory (seven) -Framework binder examples
  8. Android10.0 Binder communication theory (eight) -Framework layer analysis

0. What is AIDL

AIDL: Android Interface Definition Language, that is, Android Interface Definition Language.

Android can not share memory between processes in the system, therefore, need to provide some mechanism for data communication between different processes. In order to enable other applications can also access services provided by this application, Android system uses a Remote Procedure Call (Remote Procedure Call, RPC) manner. Like many other RPC-based solutions, Android using an interface definition language (Interface Definition Language, IDL) interfaces to public services. We know that four Android application components 3 (Activity, BroadcastReceiver and ContentProvider) can be accessed across processes, another Android Application Component Service can also be. Therefore, such a process can access services across called AIDL (Android Interface Definition Language) services.

 

AIDL will now be described by means of communication between two APP one example.

 

1. Engineering Environment to prepare

1) First create a project by Android Studio New Project -> Empty Activity, Name: AIDLDemo, Pakcage: com.android.myservice, as a Server

 

2) then create a Module in the project, used for Client, right click on the project file -> New-> Module -> Phone & Tablet Module, fill in the name of client -> Empty Activity

3) such Server and Client two environments is ready

Then start filling the code

 

 

2. The server design

2.1 Creating a file IMyService AIDL

In the folder app services, perform the following steps:

Right -> New -> AIDL-> AIDL File, name IMyService

AIDL created

Fill add a function, we used to do addition calculation:

Code:

// IMyService.aidl
package com.android.myservice;

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

interface IMyService {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

    int add(int num1, int num2);
}

Select Build -> Make Module "app", compiled AIDL will automatically generate IMyService service interface, which implements stub, proxy's class, and the code TRANSACTION, for the communication processing

2.2 Service Implementation

In the Framework layer we can also use the service addService be registered, but at the application layer, we do not have the appropriate permissions, only by integrating Service, open Service, let Client carried bind.

Create a Java Class --- MyService on JAVA-> com.android.myservice

package com.android.myservice;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class MyService extends Service {
static final String TAG = "MyTestService";
//服务实体
    IMyService.Stub mStub = new IMyService.Stub() {

        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        @Override
        public int add(int num1, int num2) throws RemoteException {
            Log.d(TAG,"add");
            //服务的接口实现,这里做一个加法运算
            return num1 + num2;
        }
    };
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG,"onBind");
        return mStub;//通过ServiceConnection在activity中拿到MyService
    }
}

2.3 AndroidManifest.xml Configuration

Service is accompanied by information in AndroidManifest.xml, which enable: ture settings are available, exported: ture of external exposure, so that other Activity for access.


<service android:name=".MyService"
    android:enabled="true"
    android:exported="true">
    <!--enable:ture设置可用
       exported:ture对外暴露 -->
    <intent-filter>
       <action android:name="com.android.myservice.myservice"/>
    </intent-filter>
</service>

Compile, the server ready, compiling a APK enter the mobile phone \ simulator

 

3.Client end design

3.1 AIDL copy

AIDL end of the service and the complete package directory are copied to the client directory of mian, let Client Server objects and services and so on.

Then compile Build-> Make Module "Client", the corresponding client is also compiled IMyService.java

3.2 Client's UI implementations

In layout-> activity_main.xml add the appropriate control, the effect is as follows:

layout:


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/toAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="计算"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/result" />

    <Button
        android:id="@+id/bindbtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="绑定服务"
        app:layout_constraintStart_toStartOf="@+id/toAdd"
        app:layout_constraintTop_toBottomOf="@+id/toAdd" />

    <Button
        android:id="@+id/unbindbtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="解除绑定"
        app:layout_constraintStart_toStartOf="@+id/bindbtn"
        app:layout_constraintTop_toBottomOf="@+id/bindbtn" />

    <EditText
        android:id="@+id/num1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="#ececec"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/num2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="#ececec"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/add" />

    <EditText
        android:id="@+id/result"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="#eceaea"
        android:inputType="none"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/value" />

    <TextView
        android:id="@+id/add"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="+"
        android:textSize="25sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/num1" />

    <TextView
        android:id="@+id/value"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="1dp"
        android:text="="
        android:textSize="25sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/num2" />

</androidx.constraintlayout.widget.ConstraintLayout>

3.3 Client service binding and function realization

Solution binding services through bindService, unbindService serving tie


package com.android.client;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.android.myservice.IMyService;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
       static final String TAG = "AIDLClient";
    IMyService myService;
    private EditText num1;
    private EditText num2;
    private EditText result;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate ");
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        num1 = (EditText) findViewById(R.id.num1);
        num2 = (EditText) findViewById(R.id.num2);
        result = (EditText) findViewById(R.id.result);

        Button toAdd = (Button) findViewById(R.id.toAdd);
        Button bindbtn = (Button) findViewById(R.id.bindbtn);
        Button unbindbtn = (Button) findViewById(R.id.unbindbtn);
        toAdd.setOnClickListener(this);
        bindbtn.setOnClickListener(this);
        unbindbtn.setOnClickListener(this);
    }

    private ServiceConnection connection = new ServiceConnection() {
        //绑定上服务的时候
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            //接受到了远程的服务
            Log.d(TAG, "onServiceConnected: ");
            myService = IMyService.Stub.asInterface(service);
        }

        // 当服务断开的时候调用
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.d(TAG, "onServiceDisconnected: ");
            //回收资源
            myService = null;

        }
    };

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bindbtn://绑定服务
                Log.d(TAG, "start to bindMyServce");
                bindMyService();
                break;
            case R.id.unbindbtn://解除绑定
                Log.d(TAG, "start to unbindMyServce");
                unbindMyService();
                break;
            case R.id.toAdd://计算数据
                int number1 = Integer.valueOf(num1.getText().toString());
                int number2 = Integer.valueOf(num2.getText().toString());
                try {
                    Log.d(TAG, "start to add");
                    int valueRes = myService.add(number1, number2);
                    result.setText(valueRes + "");
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
        }
    }

    private void bindMyService() {
        Intent intent = new Intent();
        intent.setAction("com.android.myservice.myservice");
        intent.setPackage("com.android.myservice"); // server's package name
        bindService(intent, connection, BIND_AUTO_CREATE);
        new AlertDialog.Builder(this)
                .setTitle("Tips")
                .setMessage("绑定成功!")
                .setPositiveButton("确定",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                                int whichButton) {

                            }
                        }).show();
        Log.d("AIDLClient", "bindMyService: bind on end");
    }

    private void unbindMyService() {
        unbindService(connection);
        new AlertDialog.Builder(this)
                .setTitle("Tips")
                .setMessage("解除绑定成功!")
                .setPositiveButton("确定",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                                int whichButton) {

                            }
                        }).show();
        Log.d("AIDLClient", "unbindMyService: unbind on end");
    }
}

Compile, generate client.apk, showcased on \ simulator

 

4. Test:

Click on "Bind service", after the success of pop-up "Bind success":

log:
   Client:

03-21 19:32:49.986 30794 30794 D AIDLClient: start to bindMyServce
03-21 19:32:50.023 30794 30794 D AIDLClient: bindMyService: bind on end
03-21 19:32:50.044 30794 30794 D AIDLClient: onServiceConnected:
03-21 19:32:57.062 30794 30794 D AIDLClient: start to add

Server:

03-21 19:32:49.996 31091 31091 D MyTestService: onCreate
03-21 19:32:49.997 31091 31091 D MyTestService: onBind

1 and 2 respectively inputted in the input box, clicking calculations performed "1 + 2", the result is 3, the server returns a success from

log:
Client:

 03-21 19:32:57.062 30794 30794 D AIDLClient: start to add

Server:

03-21 19:32:57.063 31091 31160 D MyTestService: add

Click "unbind", after the success of pop-up "unbind success":

log:
Client:

03-21 19:35:57.109 30794 30794 I AIDLClient: start to unbindMyServce
03-21 19:35:57.147 30794 30794 D AIDLClient: unbindMyService: unbind on end

The next section specifically to talk about the principle of AIDL

My micro-channel public number: IngresGe

Published 25 original articles · won praise 55 · views 50000 +

Guess you like

Origin blog.csdn.net/yiranfeng/article/details/105313562