Take a look, the "Framework Binder" interview questions that Internet companies love to ask

What do Internet giants ask about "Binder"? How deep is it to ask?

I believe everyone is as curious as I am. Although many of the technologies in "Binder" can only be used in projects of major Internet companies, I am not willing to be a salted fish and I still yearn for BAT. I want to win the offer in the spring recruitment next year, so the end of the year The review summary is mainly about the technical knowledge points related to the interview. Friends who have the same idea as me can refer to the "Android Interview Core Knowledge Points" I spent a few months on Github.

Interview reference

In this article, I mainly explain the Binder mechanism in the way of the interview questions I compiled. If you can write it, please leave your likes .

  • Analyze the way of communication between processes
  • The proxy class in the binder uses a dynamic proxy. Core method: mRotate.transact(Stub.TRANSACTION_xxx,_data,_reply,flags);
  • What are the advantages of Binder? (Byte beating real question)
  • How does Binder make one copy? (Tencent real question)
  • Explanation of the principle of MMAP; (Tencent real question)
  • Describe the details of the Java classes generated by AIDL; (byte beating real question)
  • The communication mechanism at the bottom of the four major components; (byte beating real question)
  • Why can't Intent deliver big data? (Ali Zhenti)

Inter-process communication method

There are many ways of inter-process communication, such as shared memory, Socket, pipe, etc., but we will not use these as Android development (and I don’t understand this one, if I need to study it later), Android The binder is used. As for the difference, as shown below.

Advantages of using binder:

  • 1. The copy only needs one time. Although there is a communication mechanism that does not require copying, it will involve the synchronization of information resources at all times. This is very performance-consuming, and the control is extremely complex, and the ease of use is also poor.
  • 2. Security, because each app is assigned a UID (can be regarded as an application ID).

Memory partition

Want to know how to transfer data, you need to understand the memory division

How do Binder and traditional IPC transfer data?

Binder compared with traditional ipc (inter-process communication mechanism)
.Traditional ipc transmission data flow.
One copy: a piece of space (virtual memory) and kernel space (virtual memory)
on the server side are mapped to the same piece of physical memory through MMP. No need to copy: sender, receiver , The shared area is mapped to the same physical memory. (It will involve the synchronization of various information resources, resulting in complex control and poor ease of use)

The upper layer implements process communication on the Android side through AIDL and the bottom layer uses Binder, and AIDL implements the inter-process communication process

Haha, this picture is drawn from my own, I feel that the interpretation of inter-process communication is very thorough. The upper layer is AIDL, the bottom layer is Binder, the client's proxy class sends data, and the ServiceManager (itself Service) class is used to find the appropriate server Service, a service (Service) needs to correspond to an AIDL, the service stub of the server receives the data, and then the Proxy of the server sends the data to the client, etc.\color{#FF0000}{The upper layer is AIDL, the bottom layer is Binder, the proxy class of the client To send data, find the appropriate server service through the ServiceManager (itself Service) class, a service (Service) needs to correspond to an AIDL, the service stub of the server receives the data, and then the proxy of the server sends the data to the client, etc.) It is AIDL, the bottom layer is Binder, the proxy class of the client sends data, and the appropriate server service is found through the ServiceManager (itself Service) class. A service (Service) needs to correspond to an AIDL, and the service stub of the server receives the data, and then The Proxy of the server sends data to the client and the whole line is complete.

How does the client get the AIDL handle, how to call the server through this handle, and how does the server handle it?

Demo example

  • 1. Engineering structure

Server


Client

  • 2. Code

I won’t say how to create a new aidl file. This is the basis.
Server

//1.ILiaoAidlInterface

package com.xm.aidl_server;

// Declare any non-default types here with import statements
import com.xm.aidl_server.Person;
interface ILiaoAidlInterface {

       List<Person> getPersonList();

       void addPerson(in Person person);
}

--------------------------------
//2.Person aidl文件

package com.xm.aidl_server;

parcelable Person;
-------------------


//3.Person对应的实体类
package com.xm.aidl_server;

import android.os.Parcel;
import android.os.Parcelable;

//1.Android开发:什么是Parcel?  http://blog.csdn.net/nkmnkm/archive/2011/05/28/6451699.aspx
//2.android开发之Parcelable使用详解  https://blog.csdn.net/u012702547/article/details/47151001/
public class Person implements Parcelable {
    private String name;
    private int grade;

    public Person(String name, int grade) {
        this.name = name;
        this.grade = grade;
    }

    protected Person(Parcel in) {
        this.name = in.readString();
        this.grade = in.readInt();
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(grade);
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", grade=" + grade +
                '}';
    }
}

-------------------------


//4.服务端app对应的服务(Service)类
package com.xm.aidl_server;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.Nullable;

public class MyService extends Service {

    private List<Person> personList;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        personList = new ArrayList<>();
        return iBinder;
    }
    private IBinder iBinder = new ILiaoAidlInterface.Stub() {
        @Override
        public List<Person> getPersonList() throws RemoteException {
            return personList;
        }

        @Override
        public void addPerson(Person person) throws RemoteException {
            personList.add(person);
        }
    };
}


--------------------------------
//5.启动服务端app的Service

public class MainActivity extends AppCompatActivity {

    private Intent intent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intent = new Intent(this, MyService.class);
        startService(intent);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopService(intent);
    }
}

The above is all the code on the server side. I originally wanted to take screenshots but posted them all because they were worried that people watching this blog could get started quickly.

Client


This code is copied from the server. To achieve inter-process communication, this code must be consistent! ! !

       Button btn = findViewById(R.id.btn);
        //1.第一步 绑定服务端service
        bindService();
        //第二步 设置按钮点击事件
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    iLiaoAidlInterface.addPerson(new Person("姓名",7));
                    List<Person> personList = iLiaoAidlInterface.getPersonList();
                    Log.i("MainActivity", "onClick: "+personList.toString());
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
        
        
 ---------------------------------------
 
 
 //2.bindService()方法
    private void bindService() {
        Intent intent = new Intent();
        //todo 为啥不能直接通过intent带参数 为啥非得这种方式  全包名、类名
        intent.setComponent(new ComponentName("com.xm.aidl_server","com.xm.aidl_server.MyService"));
        //todo 三个参数都得介绍
        //service 指的是服务端service
        //
        //参数三:flags: 为0,表示客户端可以发送到服务端,服务端也可以返回 为1,表示客户端发送到服务端,但是服务端不可以返回
       //_data:是客户端发送到服务端 _reply:是服务端可以发送到客户端
        bindService(intent,connection,0);
    }

----------------------------------------------

// 3.内部类connection 
 ServiceConnection connection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //todo
            iLiaoAidlInterface = ILiaoAidlInterface.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            //todo
            iLiaoAidlInterface = null;
        }
    };

Output

//场景1:服务端Service如果没有开启 点击客户端按钮 日志如下

2020-12-26 23:42:32.821 10001-10001/com.xm.aidl_client W/System.err:     at com.xm.aidl_client.MainActivity$1.onClick(MainActivity.java:33)
2020-12-26 23:42:54.203 10001-10001/com.xm.aidl_client W/System.err:     at com.xm.aidl_client.MainActivity$1.onClick(MainActivity.java:33)
2020-12-26 23:43:08.919 10001-10001/com.xm.aidl_client W/System.err:     at com.xm.aidl_client.MainActivity$1.onClick(MainActivity.java:33)

-----------------------------------------------------------
//场景2:服务端Service如果开启 点击客户端按钮 日志如下

2020-12-26 23:44:59.928 13635-13635/com.xm.aidl_client I/MainActivity: onClick: [Person{name='姓名', grade=7}]
2020-12-26 23:45:01.761 13635-13635/com.xm.aidl_client I/MainActivity: onClick: [Person{name='姓名', grade=7}, Person{name='姓名', grade=7}]
2020-12-26 23:45:04.672 13635-13635/com.xm.aidl_client I/MainActivity: onClick: [Person{name='姓名', grade=7}, Person{name='姓名', grade=7}, Person{name='姓名', grade=7}]

Several states when A process accesses B process

  • 1. Process B is not started
  • 2. Process B is started, but Service is not created
  • 3. Process B is started, Service is created, but Service is not bound, callback onBind()
  • 4. Process B is started, Service is created, but Service is bound, callback onRebind()

Interview reference

Guess you like

Origin blog.csdn.net/qq_39477770/article/details/111866723