AIDL基本使用1----调用服务端方法

来源:互联网 发布:日本扫码软件 编辑:程序博客网 时间:2024/06/08 11:05

    • 进程概念
    • 最基本使用方法

进程概念:

如果您想直接学使用AIDL怎么使用请跳过此处

进程:是系统分配资源的和调用的一个独立单位.

线程:共享进程所分配资源,依赖于进程,是任务执行的最小执行单元.进程孵化线程.

案例:

package com.fmy;public class Test {    private static Person person;    static class Person{        public void run(){            System.out.println("我是人类我正在跑步");        }        public void eat(){            System.out.println("我是人类我正在吃饭");        }    }    public static void main(String[] args) {        person = new Person();        //子线程完成人类吃东西任务        new Thread("线程1"){            public void run() {                person.eat();            };        }.start();        //子线程完成人类跑步任务        new Thread("线程2"){            public void run() {                person.run();            };        }.start();    }}
  • 解释:
    上面案例中运行在jvm中他就是一个系统进程.
    此案例中有三个线程:

    1. 主线程
    2. 子线程1
    3. 子线程2

    他们共同完成人类跑步和吃东西的任务

在默认情况下所有的activity,service等等 会运行在同一个app进程
中.除非另行指定.

指定service或者activitity不在app同一进城方法:
在清单文件的组件标签填写属性如:
android:process=":XXX"或者android:process="XXX.YYYY"

具体代码(任玉刚Android开发与艺术):

<activity      android:name=".MainActivity"      android:configChanges="orientation|screenSize"      android:label="@string/app_name"      android:launchMode="standard" >      <intent-filter>          <action android:name="android.intent.action.MAIN" />      </intent-filter>  </activity>  <activity      android:name=".SecondActivity"      android:configChanges="screenLayout"      android:label="@string/app_name"      android:process=":remote" />  <activity      android:name=".ThirdActivity"      android:configChanges="screenLayout"      android:label="@string/app_name"      android:process="com.ryg.chapter_2.remote" />  

上面的代码中:

  1. MainActivity没有指定process属性,所以它运行在默认的进程中,默认进程的进程名是包名。

  2. SecondActivity会运行在一个单独的进程中,进程名为“com.ryg.chapter_2:remote”,其中com.ryg.chapter_2是包名。在程序中的冒号“:”的含义是指要在当前的进程名前面附加上当前的包名,是一种简写的方法。而且以“:”开头的进程属于当前应用的私有进程,其他应用的组件不可以和它跑在同一个进程中。

  3. ThirdActivity会运行在另一个单独的进程中,进程名为“com.ryg.chapter_2.remote”。这是一种完整的命名方式。属于全局进程,其他应用通过ShareUID方式可以和它跑在同一个进程中。
    注意点一:Android系统会为每一个应用分配一个唯一的UID,具有相同UID的应用才能共享数据。要求两个应用具有相同的ShareUID并且签名相同才可以跑在同一个进程中。在这种情况下,它们可以互相访问对方的私有数据,比如data目录、组件信息等,不管它们是否跑在同一个进程中。当然如果它们跑在同一个进程中,那么除了能共享data目录、组件信息,还可以共享内存数据,或者说它们看起来就像是一个应用的两个部分。

tip:用adb shell ps 可以看到所有进程

最基本使用方法

开发工具:android studio
目的:让客户端调用服务端的一个方法,并且传入客户端可以传入参数.最终在服务端调用的时候返回字符串给客户端.首先大家先看下基本流程后面做详解

  • 创建一个module名称为myservice

  • 创建一个服务类MyService.java

  • 创建一个AIDL文件 IMyAidlInterface.aidl
    这里写图片描述

此时会在工程下的/src/main/aidl/生成对应aidl文件.这个比eclispe相比简直大幅度提升了效率

来看下这个文件的源码:

package com.ucoupon.myservice;interface IMyAidlInterface {    String basicTypes(int age, String string);}
  • 修改MyService.java
package com.ucoupon.myservice;import android.app.Service;import android.content.Intent;import android.content.ServiceConnection;import android.os.IBinder;import android.os.RemoteException;import android.support.annotation.Nullable;import android.util.Log;public class MyService extends Service {    public MyService() {    }    @Override    public void onCreate() {        super.onCreate();        Log.d(TAG, "onCreate() called");    }    //绑定的时候回调    @Nullable    @Override    public IBinder onBind(Intent intent) {        Log.d(TAG, "onBind() called with: intent = [" + intent + "]");        return new MyAidlInterface();    }    @Override    public void unbindService(ServiceConnection conn) {        Log.d(TAG, "unbindService() called with: conn = [" + conn + "]");        super.unbindService(conn);    }    @Override    public void onDestroy() {        super.onDestroy();        Log.d(TAG, "onDestroy() called");    }    private static final String TAG = "MyService";    class MyAidlInterface extends IMyAidlInterface.Stub{        /**         * 此方法用于调用服务端代码,然后返回客户端一个string类型          * @param age 从客户端传入         * @param string 从客户端传入         * @return 返回给客户端的信息         * @throws RemoteException         */        @Override        public String basicTypes(int age, String string) throws RemoteException {            Log.d(TAG, "basicTypes() called with: age = [" + age + "], string = [" + string + "]");            //返回给客户端            return age+"==="+string;        }    }}
  • 客户端
    新建一个moudle工程.直接在Activity中bindservice.

  • 把服务端的aidl文件夹拷贝到客户端工程相同位置之下

  • 在Activity执行绑定

package com.ucoupon.aidlstudy;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.IBinder;import android.os.RemoteException;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import com.ucoupon.myservice.IMyAidlInterface;public class MainActivity extends AppCompatActivity {    private Myconnect myconnect;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //连接管理        myconnect = new Myconnect();        //意图        Intent intent = new Intent();        intent.setClassName("com.ucoupon.myservice","com.ucoupon.myservice.MyService");        //开始绑定服务        bindService(intent,myconnect,BIND_AUTO_CREATE);    }    private static final String TAG = "MainActivity";    class Myconnect implements ServiceConnection {        //连接的成功的时候回调        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            Log.d(TAG, "onServiceConnected() called with: name = [" + name + "], service = [" + service + "]");            IMyAidlInterface iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);            try {                String msg = iMyAidlInterface.basicTypes(1, "客户端传入的");            } catch (RemoteException e) {                e.printStackTrace();            }            //解绑服务//            unbindService(myconnect);        }        //断开连接的时候回调        @Override        public void onServiceDisconnected(ComponentName name) {            Log.d(TAG, "onServiceDisconnected() called with: name = [" + name + "]");        }    }}

上述代码执行后:
服务端打印的日志:
这里写图片描述


客户端打印日志:
这里写图片描述

API教学和解释部分:
服务端部分:
1. 如果想让客户端调用服务端的对象方法,首先创建一个aidl文件.aidl文件可以完全当成接口去写.里面写客户端想让服务端的调用方法
如:IAAA.aidl

interface IAAA{    //想让客户端调用服务端test方法    void test();}
  • 创建完成build一下工程之后 会自动生成一个对应此IAAA接口的IAAA.java类,内部有一个Stub类

  • 接着在服务类继承自动生成的java类中的内部类Stub即可

如:

  //Myserver.java  //用此类的实例对象返回给客户端 class AAA extends IMyAidlInterface.Stub{     //客户端可以远程调用此方法     void test(){     } }

最后在 服务端的生命周期中的onBind返回该类实例化对象即可

 //Myserver.java public IBinder onBind(Intent intent) {        return new AAA();    }

客户端部分:

拷贝:aidl文件到客户端上,包名必须保持一致!!!

  • 创建一个类继承ServiceConnection
 class Myconnect implements ServiceConnection {        //连接的成功的时候回调        @Override        public void onServiceConnected(ComponentName name, IBinder service) {        }        //断开连接的时候回调        @Override        public void onServiceDisconnected(ComponentName name) {        }    }

调用bindService方法即可绑定

bindService(intent,ServiceConnection ,flag)//第一个参数 intent 没什么好讲的//第二个参数 一个继承与ServiceConnection  实例对象//第三个参数 标志 一般为BIND_AUTO_CREATE

AIDL基本使用2— 客户端传入对象

阅读全文
0 0