Binder核心机制分析,揭秘跨进程的实现原理

Android 高级工程师进阶 ~ 网易云课堂 学习笔记

什么是Binder ?

安卓的IPC机制

Linux 的驱动

安卓系统中的Binder 类,实现了IBinder接口

Binder在安卓中的使用

四大组件

系统 service 如 AMS,PMS 的实现都依赖于Binder 的通信机制

为什么要在增加 Binder机制

常见的进程间通信机制: 管道、消息队列、共享 内存和Socket

原因:基于性能、稳定性 和安全性几方面考虑

性能方面

====================================================
IPC 数据拷贝次数

共享内存 0
Binder 1
Socket/管道/消息队列 2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

稳定性方面

Binder:基于C/S架构,客户端(client)有什么需求就丢给服务端(Server)去完成
架构清晰,职责明确又相互独立,自然稳定性更好

共享内存:虽然无需拷贝,但是控制复杂,难以使用

从稳定性的角度讲 ,Binder 机制是优于共享内存的。

安全性方面

传统的IPC没有任何安全措施,安全依赖上层协议来确保
传统的IPC方法无法获得对方可靠的进程用户ID/进程ID(UID/PID)从而无法鉴别对方身份
传统的IPC只能由用户在数据包中填入UID/PID 容易被恶意程序利用
传统的IPC访问接入点是开放的,无法阻止恶意程序通过猜测接收方地址获得连接。
Binder既支持实名Binder,又支持 匿名Binder,安全性高。

一个demo 教你如何实现实现跨进程通讯

定义 aidl 文件


// Student.aidl
package com.github.yoyozhangh.studydemo;

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

parcelable Student;
// IStudentManger.aidl
package com.github.yoyozhangh.studydemo;
import  com.github.yoyozhangh.studydemo.Student;

interface IStudentManger {
    List getStudentList();
    void addStudent(in Student student);
}

界面1

package com.github.yoyozhangh.studydemo;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.github.yoyozhangh.studydemo.binder.SecondActivity;

import java.util.List;

public class BinderMainActivity extends AppCompatActivity {

    private final static String TAG = BinderMainActivity.class.getSimpleName();


    private IStudentManger mRemoteStudentManger;
    private int student_size = 2;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //获取到IstudentManger 对象
            IStudentManger iStudentManger = IStudentManger.Stub.asInterface(service);
            mRemoteStudentManger = iStudentManger;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mRemoteStudentManger = null;
            Log.e(TAG, "onServiceDisconnected.threadName :" + Thread.currentThread().getName());
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.binder_main_activity);
        Intent intent = new Intent(this, StudentMangerService.class);
        bindService(intent, connection, BIND_AUTO_CREATE);
    }

    public void toSecondActivity(View view) {
        Student.NAME = "netEase";
        startActivity(new Intent(this, SecondActivity.class));
        Log.e(TAG, "toSecondActivity name=" + Student.NAME);
    }

    public void getStudentList(View view) {
        Toast.makeText(this, "正在获取学生列表", Toast.LENGTH_SHORT).show();
        //由于服务端的查询是耗时操作
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (mRemoteStudentManger != null) {
                    try {
                        final List studentList = mRemoteStudentManger.getStudentList();
                        student_size = studentList.size();
                        Log.e(TAG, "获取到的学生列表 " + studentList.toString());
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    public void addStudent(View view) {
        if (mRemoteStudentManger != null) {
            int student_id = student_size + 1;
            Student newStudent = new Student(student_id, "zhangsan" + student_id, "man");
            try {
                mRemoteStudentManger.addStudent(newStudent);
                Log.e(TAG, "添加一位学生 " + newStudent.toString());
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }
}

界面2 SecondActivity

package com.github.yoyozhangh.studydemo.binder;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.github.yoyozhangh.studydemo.R;
import com.github.yoyozhangh.studydemo.Student;

public class SecondActivity extends AppCompatActivity {

    private final static String TAG = SecondActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e(TAG, "SecondActivity onCreate: name =" + Student.NAME);
    }
}

binder_main_activity.xml





    
  
            
                
                
            
        

StudentMangerService

package com.github.yoyozhangh.studydemo;

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

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

public class StudentMangerService extends Service {

    private static final String TAG = StudentMangerService.class.getSimpleName();
    //判断当前的service是否销毁
    private AtomicBoolean mIsServiceDestoryed = new AtomicBoolean(false);


    // 用于进程安全的传输列表类
    private CopyOnWriteArrayList mStudentList = new CopyOnWriteArrayList<>();

    @Override
    public void onCreate() {
        super.onCreate();
        //在服务端先手动添加两个学生
        mStudentList.add(new Student(1, "netease", "man"));
        mStudentList.add(new Student(2, "net", "woman"));
    }


    @Override
    public void onDestroy() {
        mIsServiceDestoryed.set(true);
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new MyStudentManger();
    }

    class MyStudentManger extends IStudentManger.Stub {

        @Override
        public List getStudentList() throws RemoteException {
            SystemClock.sleep(2000);//休眠2s 模拟服务端的耗时操作
            return mStudentList;
        }

        @Override
        public void addStudent(Student student) throws RemoteException {
            mStudentList.add(student);
        }
    }
}

        

Student

package com.github.yoyozhangh.studydemo;

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

public class Student implements Parcelable {
    public static String NAME = "THINK";


    private int s_id;
    private String s_name;
    private String s_gender;

    public Student(int s_id, String s_name, String s_gender) {
        this.s_id = s_id;
        this.s_name = s_name;
        this.s_gender = s_gender;
    }

    protected Student(Parcel in) {
        s_id = in.readInt();
        s_name = in.readString();
        s_gender = in.readString();
    }

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

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

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {

        dest.writeInt(s_id);
        dest.writeString(s_name);
        dest.writeString(s_gender);
    }


    @Override
    public String toString() {
        return "Student{" +
                "s_id=" + s_id +
                ", s_name='" + s_name + '\'' +
                ", s_gender='" + s_gender + '\'' +
                '}';
    }
}

源码地址:https://github.com/yoyo0316/StudyDemo/commit/b309c28611dbd9f1a0ee2a3b38bd16bf2ce383d9

你可能感兴趣的:(Android,高级进阶学习)