aidl 学习

来源:互联网 发布:淘宝卖动漫周边侵权吗 编辑:程序博客网 时间:2024/05/21 19:50

开发的时候要用到aidl,基础是service 所以先来了解一下service:

Service一般会重写oncreate,onstart,ondestroy方法,oncreate方法会在service初次运行的时候调用,但是它只会调用一次:

StartService à oncreate à onstart;(第一次)

如果service已经启动了:

Startservice à onstart;

 

ondestroy方法会在结束service的时候被 调用,

stopService à ondestroy

 

service还用绑定的问题,service还有另外两个方法onbind onunbind方法

activity 一般绑定已经运行的服务,

 

bindService à onbind

unbindService à onunbind

 

在bind和unbind service的时候会用到一个接口 serviceconnection

这个接口定义了两个方法 onServiceConnected 和 onServiceDisconnected 这个两个方法分别会在绑定和解绑的时候被调用

注意上面的红字表示在activity中调用的方法 

现在对service已经有基本的了解了,接下来就可以实现service三种实现方式中最简单两种了。

还有一个需要了解的概念就是service中最好有个binder内部对象这个对象继承自bind类,主要通过这个对象来获取service内部的信息以及方法。

 

接下来进入重点aidl:让其他应用程序复用该服务。这样的服务叫远程(remote)服务,实际上是进程间通信(RPC)。这时需要使用android接口描述语言(AIDL)来定义远程服务的接口,而不是上述那样简单的java接口。扩展名为aidl而不是java。这里的思想是:aidl就是类似一个接口,然后可以让service类和内部的bind类都实现这个接口,这样其他应用程序只需要通过这个接口就可以访问到service中的信息。

但是service中的binder是通过远程获得的,所以需要通过桩(Stub)来获取。桩对象是远程对象的本地代理。

下面是个aidl的例子这个例子拷贝自网上,觉得这个例子比我的要好,所以就用他的吧。

首先定义aidl文件:ICountSerivde.aidl

 

packagecom.easymorse;

interface
 ICountService { 
    
int getCount();
}

 

在src目录的任何一个子目录下创建一个aidl文件都可以,创建出aidl文件后 eclipse会自动的在gen目录下创建对应的java类

 

接下来写服务类

package com.easymorse;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class CountService extends Service {

    private boolean threadDisable;

    private int count;

    private ICountService.StubserviceBinder = new ICountService.Stub() {

        @Override
        public int getCount() throws RemoteException {
            return count;
        }
    };

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

    @Override
    public void onCreate() {
        super .onCreate();
        new Thread( new Runnable() {

            @Override
            public void run() {
                while ( ! threadDisable) {
                    try {
                       Thread.sleep( 1000 );
                   } catch (InterruptedException e) {
                   }
                   count ++ ;
                   Log.v( " CountService " , " Count is " + count);
               }
            }
        }).start();
    }

    @Override
    public void onDestroy() {
        super .onDestroy();
        this .threadDisable = true ;
        Log.v( " CountService " , " on destroy " );
    }
}

 

AndroidManifest.xml文件:

<? xml version="1.0"encoding="utf-8" ?> 
manifest xmlns:android ="http://schemas.android.com/apk/res/android" 
    package
 ="com.easymorse" android:versionCode ="1" android:versionName ="1.0" > 
    < application android:icon ="@drawable/icon" android:label ="@string/app_name" > 
        < activity android:name =".LocalServiceDemoActivity" 
           android:label
 ="@string/app_name" > 
            < intent-filter > 
                < action android:name ="android.intent.action.MAIN" /> 
                < category android:name ="android.intent.category.LAUNCHER" /> 
            </ intent-filter > 
        </ activity > 
        < service android:name ="CountService" > 
            < intent-filter > 
                < action android:name ="com.easymorse.CountService" /> 
            </ intent-filter > 
        </ service > 
    </ application > 
    < uses-sdk android:minSdkVersion ="3" /> 
</ manifest >

 

 

Activity

package com.easymorse;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

public class LocalServiceDemoActivity extends Activity {

    private ServiceConnectionserviceConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentNamename, IBinder service) {
        countService = (ICountService) service;
        try {
            Log.v( " CountService " , " on serivce connected, count is " 
                    + countService.getCount());
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void onServiceDisconnected(ComponentNamename) {
        countService = null ;
    }

};

    private ICountService countService;

    /** Called when the activity is first created. */ 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super .onCreate(savedInstanceState);
        setContentView(R.layout.main);
        this .bindService( new Intent( " com.easymorse.CountService " ),
                this .serviceConnection, BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {

          this .unbindService(serviceConnection);        

          super .onDestroy();       //注意先后 
    }
}

 

 

编写传递复杂数据类型的远程服务

远程服务往往不只是传递java基本数据类型。这时需要注意android的一些限制和规定:

android支持String和CharSequence

如果需要在aidl中使用其他aidl接口类型,需要import,即使是在相同包结构下;

android允许传递实现Parcelable接口的类,需要import;

android支持集合接口类型List和Map,但是有一些限制,元素必须是基本型或者上述三种情况,不需要import集合接口类,但是需要对元素涉及到的类型import;

非基本数据类型,也不是String和CharSequence类型的,需要有方向指示,包括in、out和inout,in表示由客户端设置,out表示由服务端设置,inout是两者均可设置。

 

最后贴上学习的网址:http://yangguangfu.iteye.com/blog/699306


最后在补充一点,如果service和药获取service 的activity不在同一个程序内,则通过activity 里面intent的setaction("这里是service的action")来得到这个service

 

原创粉丝点击