Simple application examples of bindService and AIDL

Posted by bobthebuilder on Mon, 12 Aug 2019 14:11:21 +0200

1.Service is not a separate process, it is in the same process as its application.
2.Service is not a thread, which means we should avoid time-consuming operations in Service.

Not to mention more, we directly go to the code, it is bingService to start the service, startService is not yet.... Through bindservice, service and avtivity can communicate...

First, create a TestService One inheritance Service;

public class TestServiceOne extends Service {
    private static final String TAG = "TestServiceOne";
    private int count;
    private boolean quit;
    private MyBinder binder = new MyBinder();

    public class MyBinder extends Binder{
        public int getCount(){
            return count;
        }
    }
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind Method is called!");
        return binder;
    }
    @Override
    public void onCreate(){
        super.onCreate();
        Log.i(TAG, "onCreate Method is called!");
       Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
            while (!quit){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count++;
            }
            }
        });
        thread.start();
    }
@Override
    public int onStartCommand(Intent intent, int flags, int startId){
        return super.onStartCommand(intent,flags,startId);
}
    public boolean onUnBind(Intent intent){
        Log.i(TAG, "onUnbind Method is called!");
        return super.onUnbind(intent);
    }
@Override
    public void onDestroy(){
        this.quit=true;
        super.onDestroy();
    Log.i(TAG, "onDestroyed Method is called!");
}

}
public class Main6Activity extends AppCompatActivity {
    private Button button1;
    private Button button2;
    private Button button3;
    TestServiceOne.MyBinder binder;
    private ServiceConnection conn = new ServiceConnection() {
        //Callback method when the connection between activity and service is successful
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            binder = (TestServiceOne.MyBinder)service;

        }
        //Callback method when activity and service disconnect
        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main6);
        button1 = (Button) findViewById(R.id.bangding);
        button2 = (Button) findViewById(R.id.jiechubangding);
        button3 = (Button) findViewById(R.id.status);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Main6Activity.this,TestServiceOne.class);
                bindService(intent,conn,Service.BIND_AUTO_CREATE);
            }
        });
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                unbindService(conn);
            }
        });
        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i("TestServiceOne",binder.getCount()+"");
            }
        });
    }
}

These three buttons are ordinary buttons, through which you can see the printed log.

Summary: Step 1: Implementing your own IBinder object by inheriting Binder from a custom Service
Step 2: Return your own IBinder object through the onBind() method
Step 3: Define a Service Connection object in the class that binds the Service, override two methods, onService Connected and onDisconnected! Then read the parameters passed by IBinder directly!

Here is an example of AIDL:

AIDL (Android Interface Description Language) is an IDL language. It can generate a piece of code, which can be an interaction between two processes running on Android devices using internal communication processes. Used for different process interactions

Step 1: Create an aidl folder under the main folder, and create a package name. I'm using com.example.zhujunxian.contentprivodertest. Create a DIAL file named IPerson under this package, and then we change the code inside to this.

// IPerson.aidl
package com.example.zhujunxian.contentprivodertest;

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

interface IPerson {

     int add(int arg1, int arg2);

}

Then let's compile Ctrl+F9. At this point, we will generate the same IPerson under build/generated/source/aidl/debug/com.example.zhujunxian.content privodertest, as shown in the figure:

Below this directory are mainly auto-generated...

Then we write a Myservice inheritance Service ourselves, code as follows

public class MyService extends Service {
    IPerson.Stub mStub = new IPerson.Stub() {
        @Override
        public int add(int arg1, int arg2) throws RemoteException {
            return arg1 + arg2;
        }
    };
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return mStub;
    }
}

The main thing here is to define a method of adding two parameters.

We add it to the list file.

<service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"
            android:process=":remote"
            >
            <intent-filter>
                <action android:name="co.example.leo.myService"/>
            </intent-filter>
        </service>

Then we re-create a project to mimic another process... The project name is MyAidlDemoCustomer, and then copy the aidl folder under the main directory of the project we just created directly to our new project... One thing is that our registration must be the same...

Then we create an Activity test.

public class MainActivity extends AppCompatActivity {
    TextView textView;
    IPerson mSub;
    private static final String TAG = "MainActivitya";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.tv);
        Intent intent = new Intent();
        intent.setAction("co.example.leo.myService");
        intent.setPackage("com.example.zhujunxian.contentprivodertest");
        bindService(intent, connection, BIND_AUTO_CREATE);
    }

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mSub = IPerson.Stub.asInterface(service);
            if (mSub == null) {
                Log.i(TAG, "onServiceConnected: ");
            } else {
                try {
                    int value = mSub.add(2, 8);
                    textView.setText(value + "");
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onDestroy() {
        //Unbundling service
        super.onDestroy();
        unbindService(connection);
    }

}

Then when we start the application, we call the method of our other application directly... Details will be added later.

Topics: Android