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"
- Android System Architecture
- Android is how to start
- Android 10.0 system starts the init process
- Android10.0 system startup process of Zygote
- Android 10.0 system startup process of SystemServer
- Android 10.0 System Services of ActivityMnagerService
- Android10.0 system starts the Launcher (Desktop) to start the process
- Android10.0 application process as well as the creation of Zygote fork process
- Android 10.0 PackageManagerService (a) works and start the process
- Android 10.0 PackageManagerService (ii) allowed to scan
- Android 10.0 PackageManagerService (three) scanning APK
- Android 10.0 PackageManagerService (four) installation process APK
"Log System chapter"
- Android10.0 log analysis system (a) -logd, logcat instruction description, classification and properties
- Android10.0 log analysis system (b) -logd, logcat architecture analysis and log system initialization
- Android10.0 log analysis system (C) -logd, logcat log write source code analysis
- Android10.0 logging system analysis (four) -selinux, kernel log in to achieve in logd
"Binder communication principle" :
- Android10.0 Binder communication principle (one) Binder, HwBinder, VndBinder Overview
- Android10.0 Binder communication theory (b) -Binder Beginners
- Android10.0 Binder communication theory (c) -ServiceManager articles
- Android10.0 Binder communication theory (four) -Native-C C ++ case study \
- Android10.0 Binder communication theory (five) -Binder Driving
- How Android10.0 Binder communication theory (six) -Binder complete data directed against
- Android10.0 Binder communication theory (seven) -Framework binder examples
- 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