zoukankan      html  css  js  c++  java
  • 多进程通讯笔记 android aidl

    环境

    android studio 2.2

    步骤:创建aidl文件,编写service,activity中绑定service

    在项目上点击创建 aidl文件,会自动创建相关目录和文件 app/aidl/jlsky.myaidl/IMaidl.aidl。修改文件如下

    package jlsky.myaidl;
    interface IMaidl {
    int sum(int num1,int num2);
    }
    ctrl+F9,或者点击那个锤子的图标,生成java代码。如果不是深入研究,生成的java文件就不用关心了。
    创建service文件。
    public class SumService extends Service {
    private static final String TAG = "service";

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

    private IMaidl.Stub iBinder = new IMaidl.Stub(){
    @Override
    public int sum(int num1,int num2) throws RemoteException{
    return num1 + num2 ;
    }
    };

    @Override
    public void onCreate() {
    super.onCreate();
    Log.i(TAG, " onCreate");
    }
    @Override
    public boolean onUnbind(Intent intent) {
    Log.i(TAG, " onUnbind");
    return super.onUnbind(intent);
    }
    @Override
    public void onDestroy() {
    Log.i(TAG, " onDestroy");
    super.onDestroy();
    }
    }
    重点是private IMaidl.Stub iBinder = new IMaidl.Stub()中的<IMaidl>要与你的aidl的文件名一致。里面实现的方法就是在aidl中的声明一致。
    然后这个<iBinder>在service被绑定时,通过onBind()返回给activity。

    在activity中绑定service。
    比如在activity的onCreate中绑定service
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("jlsky.myaidl","jlsky.myaidl.SumService"));
    //intent.setAction("jlsky.myaidl.SumService"); //如此写是错误的!
    boolean b = bindService(intent,conn,BIND_AUTO_CREATE);
    intent的参数是service的包名和service的全称。
    b,不是必要的,但可以判断b的值来了解是否绑定成功。
    事先声明一下
    private IMaidl maidl;  //与aidl文件名一致。
    conn的来历如下,(直接放在activity中即可。)
    private ServiceConnection conn = new ServiceConnection(){
    // private class Conn implements ServiceConnection{
    @Override
    public void onServiceConnected(ComponentName name, IBinder iBinder){
    maidl = IMaidl.Stub.asInterface(iBinder);
    Log.d(TAG, "onServiceConnected: aidl");
    }
    @Override
    public void onServiceDisconnected(ComponentName name){
    maidl=null;
    Log.d(TAG, "onServiceDisconnected: aidl");
    }
    };
    activity的完整代码如下:
    public class MainActivity extends Activity {
    private EditText tv1,tv2;
    private TextView tv3;
    private Button btnSum;
    private IMaidl maidl; //from ServiceConnection
    private final static String TAG ="MainActivity";
    // private ServiceConnection conn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    bindaidl();
    Log.d(TAG, "onCreate: bindaidl");
    initview();
    Log.d(TAG, "onCreate: initview");
    }

    @Override
    protected void onDestroy() {
    super.onDestroy();
    unbindService(conn);
    Log.d(TAG, "onDestroy: unbindService");
    }

    private void initview() {
    tv1=(EditText)findViewById(R.id.tv1);
    tv2=(EditText)findViewById(R.id.tv2);
    tv3=(TextView)findViewById(R.id.tv3);
    btnSum=(Button)findViewById(R.id.btnSum);
    btnSum.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View view) {
    String str1,str2;
    str1=tv1.getText().toString();
    str2=tv2.getText().toString();
    if(str1.length()>0 && str2.length()>0){
    int data1,data2,result;
    try{
    result = maidl.sum(Integer.parseInt(str1),Integer.parseInt(str2));
    Log.d(TAG, "onClick: result"+result);
    // tv3.setText(""+result); //int to String
    tv3.setText(String.valueOf(result));//int to String
    } catch (RemoteException e) {
    e.printStackTrace();
    }
    }else{
    Toast.makeText(getApplicationContext(),"Pls input",Toast.LENGTH_SHORT).show();
    }
    }
    });
    }

    private void bindaidl(){
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("jlsky.myaidl","jlsky.myaidl.SumService"));
    //intent.setAction("jlsky.myaidl.SumService"); //it is failed for here !
    boolean b = bindService(intent,conn,BIND_AUTO_CREATE);
    if(b){
    Log.d(TAG, "bindaidl: ok");
    }else{
    Log.d(TAG, "bindaidl: fault");
    }
    }

    private ServiceConnection conn = new ServiceConnection(){
    // private class Conn implements ServiceConnection{
    @Override
    public void onServiceConnected(ComponentName name, IBinder iBinder){
    maidl = IMaidl.Stub.asInterface(iBinder);
    Log.d(TAG, "onServiceConnected: aidl");
    }
    @Override
    public void onServiceDisconnected(ComponentName name){
    maidl=null;
    Log.d(TAG, "onServiceDisconnected: aidl");
    }
    };
    }

    manifest中的定义如下
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="jlsky.myaidl">
    <application ...>
    <service
    android:name=".SumService"
    android:enabled="true"
    android:exported="true"
    android:process=":sum">
    <intent-filter>
    <action android:name="jlsky.myaidl"></action>//用来启动服务
    </intent-filter>
    </service>
    <activity android:name=".MainActivity">
    <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    </activity>
    </application>
    </manifest>
    这个定义是让service单独作为一个进程(不是线程)。省略包名的默认写法。定义为私有线程,这与以点作为分割的公有线程不同。
    android:process=":sum"
    贴出来的代码都是反复实验的结果。有些测试由于记不住了是怎么回事,以免误导,就不写说明了。
  • 相关阅读:
    2019 SDN第二次上机作业
    2019 SDN上机第1次作业
    第五次软工作业结对编程
    JIRA中的核心概念
    产品经理与项目经理的区别
    掀起你的盖头来:浅谈项目管理办公室(PMO)
    你大概走了假敏捷:认真说说敏捷的实现和问题(手绘版)
    项目管理经验
    项目经理面试中可能遇到的问题
    回到网易8个月测试团队转型实践
  • 原文地址:https://www.cnblogs.com/htsky/p/6370099.html
Copyright © 2011-2022 走看看