zoukankan      html  css  js  c++  java
  • 方法接口Service与AIDL详解

    PS:今天上午,非常郁闷,有很多简单基础的问题搞得我有些迷茫,哎,代码几天不写就忘。目前又不当COO,还是得用心记代码哦!

        Service是android中的服务组件, 经常用来行执一些行运在台后的耗时作操。 应用一个Service要需继承Service类, 并根据要需写重生命周期方法。 Service的生命周期如下:

        

    方法和接口

        public abstract IBinder onBind (Intent intent): 该方法是一个抽象方法, 因此Service类子必须实现这个方法。 它返回一个IBinder象对, 应用程序可以通过这个象对与Service组件通信(关于这一点, 其后会有细详的解讲), 以bindService()式方启动Service时调回该方法。
    public void onCreate (): 当Service第一次被创立后调回的方法。
    public void onDestroy (): Service关闭之前调回的方法。
    public int onStartCommand (Intent intent, int flags, int startId): 以startService(Intent intent)的式方启动Service时, 系统都市调回该方法。

    public boolean onUnbind (Intent intent): 当有所绑定该Service的组件都断开连接时调回该方法。

    从图中可以看出, Service可以有两种启动式方:
    1. 以startService(Intent intent)的式方启动。 此时启动的Service与用调者之间没有关联, 即应用调者经已退出, Service仍然可以继承行运, 而且用调者和Service之间没法停止数据交换和通信。 如果要需停止Service的行运, 只能用调Context类的stopService(intent)方法, 或者由Service本身用调其stopSelf()等方法。
    2. 以bindService(Intent service, ServiceConnection conn, int flags)的式方启动。
    此时用调者与Service绑定在一同, 如果用调者退出, 则Service也随之退出, 而且用调者和Service之间可以停止数据交换或通信。

    根据用调者和Service否是在一个应用程序内, 可以将用调者和Service之间的通信分为进程内通信和进程间通信。
    a. 进程内通信。 bindService(Intent service, ServiceConnection conn, int flags)方法的第二个参数为ServiceConnection象对, 最后一个参数平日可所以Service。BIND_AUTO_CREATE。 ServiceConnection是一个接口, 该接口含包2个方法:
    onServiceConnected(ComponentName name, IBinder service): 该方法在用调者和Service胜利绑定之后由系统调回。
    方法中的第一个参数ComponentName是所绑定的Service的组件名称, 而IBinder象对就是Service中onBinder()方法的返回值。 要实现用调者和Service之间的通信, 只要需用调IBinder象对中义定的方法便可。

    onServiceDisconnected(ComponentName name): 该方法在用调者消除和Service的绑定之后由系统调回。

    以下是用利Service实现进程内通信的一个例子。
    首先自义定Service类:
    Java代码

        

    ?
    代码段片,双击制复
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    publicclassMyServiceextendsService {
    publicclassMyBinderextendsBinder {
    /**
    * 取获Service的行运时间
    * @return
    */
    publiclonggetServiceRunTime() {
    returnSystem.currentTimeMillis() - startTime;
    }
    }
    privatelongstartTime;
    /**
    * MyBinder是Binder的类子, 而Binder实现了IBinder接口。
    */
    @Override
    publicIBinder onBind(Intent intent) {
    returnnewMyBinder();
    }
    @Override
    publicvoidonCreate() {
    super.onCreate();
    startTime = System.currentTimeMillis();
    }
    }

        
    然后在activity中绑定上述的Service:

    Java代码

        

    ?
    代码段片,双击制复
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    publicclassMainActivityextendsActivity {
    privateMyBinder binder = null
    /** Called when the activity is first created. */
    @Override
    publicvoidonCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    // 创立一个指向MyService的intent
    Intent intent = newIntent("cn.xing.action.my_service");
    this.bindService(intent,newMyServiceConnection(),
    Service.BIND_AUTO_CREATE);
    Button button = (Button) this.findViewById(R.id.button);
    button.setOnClickListener(newView.OnClickListener() {
    @Override
    publicvoidonClick(View v) {
    if(binder != null) {
    Toast.makeText(getApplicationContext(),"MyService经已行运了"+ binder.getServiceRunTime()
    +"毫秒", Toast.LENGTH_LONG).show();
    }
    }
    });
    }
    /**
    * 实现ServiceConnection接口
    *
    * @author xing
    *
    */
    privatefinalclassMyServiceConnectionimplementsServiceConnection {
    /**
    * 和MyService绑时定系统调回这个方法
    */
    @Override
    publicvoidonServiceConnected(ComponentName name, IBinder service) {
    // MyService中的onBinder()方法的返回值实际上是一个MyBinder象对, 因此可以应用制强转换.
    binder = (MyBinder) service;
    }
    /**
    * 消除和MyService的绑时定系统调回这个方法
    */
    @Override
    publicvoidonServiceDisconnected(ComponentName name) {
    // 消除和MyService的绑定后, 将binder设置为null.
    binder = null
    }
    }
    }

        
    b.进程间通信。 用调者和Service如果不在一个进程内, 就要需应用android中的近程Service用调机制。

    android应用AIDL义定进程间的通信接口。 AIDL的语法与java接口似类, 要需注意以下几点:
    1. AIDL文件必须以.aidl作为后缀名。
    2.AIDL接口中用到的数据类型, 除了基本类型, String, List, Map, CharSequence以外, 其他类型都要需导包, 即使两种在同一个包内。 List和Map中的元素类型必须是AIDL持支的类型。
    3. 接口名要需和文件名同相。
    4. 方法的参数或返回值是自义定类型时, 该自义定的类型必须实现了Parcelable接口。
    5. 有所非java基本类型参数都要需加上in, out, inout记标, 以明表参数是输入参数, 输出参数, 还是输入输出参数。
    6. 接口和方法前不能应用访问饰修符和static, final等饰修。

    上面通过一个例子来演示android近程Service用调机制的各个骤步:
    1. 创立remoteService项目。
    2. 在cn.xing.remoteservice包下义定aidl文件--IRemoteService.aidl:
    Java代码

        

    ?
    代码段片,双击制复
    01
    02
    03
    04
    packagecn.xing.remoteservice;
    interfaceIRemoteService{
    intgetServiceRunTime();
    }
        每日一道理
    人生是洁白的画纸,我们每个人就是手握各色笔的画师;人生也是一条看不到尽头的长路,我们每个人则是人生道路的远足者;人生还像是一块神奇的土地,我们每个人则是手握农具的耕耘者;但人生更像一本难懂的书,我们每个人则是孜孜不倦的读书郎。

        
    Eclipse的ADT件插会在gen目录的cn.xing.remoteservice包下主动根据aidl文件生成IRemoteService接口。
    接口中有一个static的抽象内部类Stub, Stub类继承了Binder类并实现了IRemoteService接口。 Stub类有如下的静态方法:
    public static cn.xing.remoteservice。IRemoteService asInterface(android.os.IBinder obj)
    该方法受接一个IBinder象对, 返回值是IRemoteService的instance, 通过这个instance我们就能够用调IRemoteService中义定的方法了。

    3. 在remoteService项目的cn.xing.remoteservice包下创立近程服务类RemoteService:

    Java代码

        

    ?
    代码段片,双击制复
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    publicclassRemoteServiceextendsService {
    privatelongstartTime;
    /**
    * IRemoteService.Stub类实现了IBinder和IRemoteService接口
    * 因此Stub的类子象对可以作为onBinder()方法的返回值.
    * @author xing
    *
    */
    publicclassMyBinderextendsIRemoteService.Stub {
    @Override
    publiclonggetServiceRunTime()throwsRemoteException {
    returnSystem.currentTimeMillis() - startTime;
    }
    };
    @Override
    publicIBinder onBind(Intent intent) {
    returnnewMyBinder();
    }
    @Override
    publicvoidonCreate() {
    super.onCreate();
    startTime = System.currentTimeMillis();
    }
    }

        
    4. 创立一个新的android项目invokeRemoteService, 并制复remoteService项目中的aidl文件(连同包结构一同制复)到invokeRemoteService项目中。

    5. 在invokeRemoteService项目中绑定近程服务, 并用调近程方法。

    Java代码

        

    ?
    代码段片,双击制复
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    publicclassMainActivityextendsActivity {
    privateIRemoteService iRemoteService = null
    /** Called when the activity is first created. */
    @Override
    publicvoidonCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    // 创立一个指向RemoteService的intent
    Intent intent = newIntent("cn.xing.action.remote_service");
    this.bindService(intent,newMyServiceConnection(),
    Service.BIND_AUTO_CREATE);
    Button button = (Button) this.findViewById(R.id.button);
    button.setOnClickListener(newView.OnClickListener() {
    @Override
    publicvoidonClick(View v) {
    if(iRemoteService != null) {
    try{
    Toast.makeText(getApplicationContext(),"MyService经已行运了"+ iRemoteService.getServiceRunTime()
    +"毫秒", Toast.LENGTH_LONG).show();
    }catch(RemoteException e) {
    e.printStackTrace();
    }
    }
    }
    });
    }
    /**
    * 实现ServiceConnection接口
    *
    * @author xing
    *
    */
    privatefinalclassMyServiceConnectionimplementsServiceConnection {
    /**
    * 和RemoteService绑时定系统调回这个方法
    */
    @Override
    publicvoidonServiceConnected(ComponentName name, IBinder service) {
    // 此处不能应用制强转换, 应当用调Stub类的静态方法得获IRemoteService接口的例实象对
    iRemoteService = IRemoteService.Stub.asInterface(service);
    }
    /**
    * 消除和RemoteService的绑时定系统调回这个方法
    */
    @Override
    publicvoidonServiceDisconnected(ComponentName name) {
    // 消除和RemoteService的绑定后, 将iRemoteService设置为null.
    iRemoteService = null
    }
    }
    }

    文章结束给大家分享下程序员的一些笑话语录: 那是习惯决定的,一直保持一个习惯是不好的!IE6的用户不习惯多标签,但是最终肯定还是得转到多标签的浏览器。历史(软件UI)的进步(改善)不是以个人意志(习惯)为转移的!

  • 相关阅读:
    WINCE串口打印信息的屏蔽与打开
    WINCE系统时间设置
    WINCE调试常见错误
    今天开始研究arcgisserver
    今天开始,放弃项目管理,做技术了
    java数据库连接
    [转]建一个XMLHttpRequest对象池
    Linux下jsp开发环境,apache,tomcat服务器配置过程
    div+css布局漫谈
    新图纸总结
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3061653.html
Copyright © 2011-2022 走看看