preface

Recently, when using Android Studio to develop, we need to use system classes. Importing jar packages can solve this problem, but because the application needs to be platform compatible, importing JAR packages can make the APP look bloated. Finally consider the use of AIDL, APP end as a client, system source code to achieve the server.

The body of the

AIDL is an acronym that stands for Android Interface Definition Language. Mainly used for interprocess communication. The following details how the server and client can create the AIDL and have the two processes communicate.

The service side

Here the server is in the system source code, online search information, said to create an AIDL file first, and then add AIDL file compilation in the Android.mk file, will generate a corresponding Java file. Toss about for a long time, did not produce a Java file, pit. If no Java file is generated, you can create one yourself.

Create an AIDL file

AIDL interface. An AIDL file is required to describe the interface supported by the server. The interface style of AIDL is as follows:

//ITestService.aidl
package com.xxx.yyy;
interface ITestService {
    boolean write(String str);
    String read();
}
Copy the code

Here, the AIDL file refers to the package name of the process where the server resides.

The AIDL file is referenced in the Android.mk file

The android. mk file is the compilation rule for the entire process. After the AIDL file is added, you need to add the AIDL file to it; otherwise, the compilation will fail.

LOCAL_SRC_FILES += $(call all-Iaidl-files-under, src)
Copy the code

This means compiling the AIDL file.

Create the corresponding Java file for AIDL

Since we can’t generate Java files for AIDL, we have to create Java files ourselves. The Java file is created as follows:

//TestService.java package com.xxx.yyy; import android.content.Context; import android.content.IntentFilter; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; public class TestService extends Service { static private final String TAG = "TestService"; @Override public void onCreate() { super.onCreate(); } ITestService.Stub mBinder = new ITestService.Stub() { @Override public boolean write(String str) throws RemoteException { return false; } @Override public String read() throws RemoteException { return null; }}; @Override public IBinder onBind(Intent intent) { return mBinder; }}Copy the code

Androidmanifest.xml registration service

After adding the AIDL and Java files on the server side, you also need to register the service in the androidmanifest.xml file as follows:

<service android:name=".TestService"
        android:process=":remote"
        android:exported="true">
        <intent-filter>
            <action android:name="com.xxx.yyy.TestService"/>
        </intent-filter>
</service>
Copy the code

At this point, the work on the server side is done.

The client

The client is developed using AS, so we need to create an AIDL file in AS AS well, otherwise AS has no interface to call. Copy the AIDL file directly from the server. Of particular interest here is the path to the AIDL file. If the paths do not match, AS compiles an error. By path matching, it means that in the AIDL file, the file path where the AIDL file resides must match the package name referenced by the AIDL file. Here is an example. First place the AIDL file path:

as_project/src/main/aidl/com/xxx/yyy/ITestService.aidl
Copy the code

First, create an aiDL folder in the main directory. The next directory level follows the package name in the aiDL file:

package com.xxx.yyy;
Copy the code

The client binds the service

After copying the AIDL file, the next step is to bind the client to the service, using the interface of the server. First paste the code:

import com.xxx.yyy.ITestService; static private ITestService mTestService; static private ServiceConnection mCon; void init(Context context) { mCon = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mTestService = ITestService.Stub.asInterface((IBinder) service); Log.d(TAG,"onServiceConnected! "); } @Override public void onServiceDisconnected(ComponentName name) { Log.d(TAG,"onServiceDisconnected! "); }}; Intent intent = new Intent(); intent.setPackage("com.xxx.yyy"); Boolean res = context.bindService(intent, mCon, Context.BIND_AUTO_CREATE); }Copy the code

The init method is called in the activity’s onCreate method.

There are two things to note here:

If the intent is not the name of the server’s package, false is returned. If the intent is not the name of the server’s package, false is returned.

2. If your interface is connected to a connected node, you will have to wait for the connected interface to call onServiceConnected ected nodes. Otherwise, you will get a null exception.

Server-side method invocation

try {
    boolean res = mTestService.write(str);
}catch (Exception e) {
    e.printStackTrace();
}
Copy the code

conclusion

This is the end of the AIDL implementation.

interactive

If the article has the wrong description, can leave a message directly, discuss together!

Articles that may be of interest

Android System Framework

Android status bar height 0 is still displayed

Tread hole NavigationBar hidden or not

The last

I also write articles in wechat public number, update more timely, interested people can pay attention to the following public number!