桥下红药

以无心之心读书

Binder在应用层的使用

总分类 0 评

之前记录的是 Binder 在系统里面的大概过程:

  1. 注册服务(addService):Server进程要先注册Service到ServiceManager。
  2. 获取服务(getService):Client进程使用某个Service前,须先向ServiceManager中获取相应的Service。
  3. 使用服务:Client根据得到的Service信息建立与Service所在的Server进程通信的通路,然后就可以直接与Service交互。

这里的Service 非 四大组件 Service

Native 层使用Binder需要写c++代码,这个跳过。Framework 层和 aidl 方式差别不大,差别就是可以直接使用 ServiceManager 注册 Service , 自己应用层反射 addService 也无法通过安全机制验证,所以使用 四大组件 Service 来完成多进程Binder通信。

#新建个项目 Server

  1. 新建个aidl文件
interface ITestAidl {

    void say(String str);

    String getName();

}

然后 Build -> Make Project IDE会自动编译生成Java同名接口。

2. 创建四大组件之一的Service


public class MyService extends Service { private static final String TAG = MyService.class.getSimpleName(); public MyService() { } Binder iTestAidl = new ITestAidl.Stub() { @Override public void say(String str) throws RemoteException { Log.i(TAG, "say : " + str); } @Override public String getName() throws RemoteException { return "我是服务端"; } }; @Override public void onCreate() { super.onCreate(); Log.i(TAG, "onCreate"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { return iTestAidl; } }

#再新建个项目 Client

  1. 把Server项目下的aidl文件原封不动带目录一起复制到Client项目里,然后再 Make Project 一下。
public class MainActivity extends AppCompatActivity {

    EditText etView;
    View btn1, btn2, btn3;

    ITestAidl mService;
    ServiceConnection serviceConnection;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        etView = findViewById(R.id.et_view);
        btn1 = findViewById(R.id.btn_1);
        btn2 = findViewById(R.id.btn_2);
        btn3 = findViewById(R.id.btn_3);

        // 调用 server say
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String str = etView.getText().toString();
                try {
                    mService.say(str);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });

        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                try {
                    Toast.makeText(MainActivity.this, "" + mService.getName(), Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });


        btn3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                serviceConnection = new ServiceConnection() {
                    @Override
                    public void onServiceConnected(ComponentName name, IBinder service) {
                        Log.i("Client","onServiceConnected");
                        mService = ITestAidl.Stub.asInterface(service);
                    }

                    @Override
                    public void onServiceDisconnected(ComponentName name) {
                        mService = null;
                    }
                };

                boolean ret = connectService();

                Toast.makeText(MainActivity.this, "" + ret, Toast.LENGTH_SHORT).show();

            }
        });

    }

    public boolean connectService() {
        if (mService == null) {

            Intent it = new Intent();

            it.setComponent(new ComponentName("aidl.com.server","aidl.com.server.MyService"));

            return this.bindService(it, serviceConnection,BIND_AUTO_CREATE);

        }
        return true;
    }

}

上一篇

发表评论