zoukankan      html  css  js  c++  java
  • Android网络课程笔记-----AIDL

    AIDL:Android接口定义语言Android Interface Definition Language (AIDL)
    官方文档链接:http://developer.android.com/guide/components/aidl.html
    
    一. 使用AIDL的步骤:
    1. 新建一个interface,声明Activity需要调用Service的方法
    2. 修改接口文件的扩展名为“.aidl”,点击项目,按F5刷新
    3. 拷贝aidl文件到客户端项目中,
        注意:aidl所在报名必须完全一致
    4. Service中的Binder继承aidl文件名.Stub
    5. 在Activity中的onServiceConnected()方法中,
        mMService = IMyService.Stub.asInterface(service);
    实现了Activity所在进程对Service所在进程的方法调用
    
    二. Activity进程调用Service进程,获取任意类型返回值
    1. 自定义类型,实现Parcelable接口
        提示:参照Parcelable的doc
    2. 创建一个与自定义类型同名的aidl文件,
        内容:parcelable 自定义类型类名
    
    在aidl接口中就可以使用这个类型了
    注意:即使在同一个包中,也要导入
             import com.yuchen.aidl.Student;

    下面提供一个复合型的AIDL实例

    首先考虑Service模块
     
    有两个.aidl文件
    package com.aidl.service;
    
        parcelable Person;
    package com.aidl.service;
    
       import com.aidl.service.Person;
    
       interface IStockQuoteService
       {
            String getQuote(in String ticker, in Person requester);
       }
    然后是.aidl文件的实现类
    public class Person implements Parcelable {
    
        private int age;
        private String name;
        
        public static final Parcelable.Creator<Person> CREATOR = new Creator<Person>() {
            
            @Override
            public Person[] newArray(int size) {
                // TODO Auto-generated method stub
                return new Person[size];
            }
            
            @Override
            public Person createFromParcel(Parcel source) {
                // TODO Auto-generated method stub
                return new Person(source);
            }
        };
        
        public Person(){
            
        }
        
        public Person(Parcel in){
            readFromParcel(in);
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public int describeContents() {
            // TODO Auto-generated method stub
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel out, int flags) {
            // TODO Auto-generated method stub
            out.writeInt(age);
            out.writeString(name);
        }
        
        public void readFromParcel(Parcel in) {
            // TODO Auto-generated method stub
            age = in.readInt();
            name = in.readString();
        }
    
    }
    public class StockQuoteService extends Service {
    
        private NotificationManager notificationManager;
        
        public class StockQuoteServiceImpl extends IStockQuoteService.Stub{
    
            @Override
            public String getQuote(String ticker, Person requester) throws RemoteException {
                // TODO Auto-generated method stub
                return "Hello" + requester.getName() + "! Quote for " + ticker + "is 20.0";
            }
            
        }
    
        @Override
        public void onCreate(){
            super.onCreate();
            notificationManager = (NotificationManager)this.getSystemService(NOTIFICATION_SERVICE);
            displayNotificationMessage("onCreate() called in StockQuoteService");
        }
        
        @SuppressWarnings("deprecation")
        private void displayNotificationMessage(String message) {
            // TODO Auto-generated method stub
            Notification notification = new Notification(R.drawable.emo_im_winking,message,System.currentTimeMillis());
            PendingIntent contentIntent = PendingIntent.getActivity(this,0,new Intent(this,MainActivity.class),0);
            notification.setLatestEventInfo(this, "StockQuoteService", message, contentIntent);
            notification.flags = Notification.FLAG_NO_CLEAR;
            notificationManager.notify(R.id.app_notification_id, notification);
        }
    
        @Override
        public void onDestroy(){
            super.onDestroy();
            displayNotificationMessage("onDestroy() called in StockQuoteService");
            notificationManager.cancelAll();
        }
        
        @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
            displayNotificationMessage("onBind() called in StockQuoteService");
            return new StockQuoteServiceImpl();
        }
    }

    配置文件

    <service android:name="com.aidl.service.StockQuoteService" >
                <intent-filter>
                    <action android:name="com.aidl.service.IStockQuoteService" />
                </intent-filter>
      </service>
    然后就是Client模块
    注意:在Client模块中,必须把在Service模块中的.aidl文件以及JavaBean类连包结构一起移到Client代码中

    然后就是视图的实现了

    public class MainActivity extends Activity {
    
        private static final String TAG = "StockQuoteClient";
        private IStockQuoteService stockService = null;
        private ToggleButton bindBtn;
        private Button callBtn;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            bindBtn = (ToggleButton) findViewById(R.id.bindBtn);
            bindBtn.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    
                @Override
                public void onCheckedChanged(CompoundButton buttonView,
                        boolean isChecked) {
                    // TODO Auto-generated method stub
                    if (isChecked) {
                        bindService(new Intent(IStockQuoteService.class.getName()),
                                serConn, Context.BIND_AUTO_CREATE);
                    } else {
                        unbindService(serConn);
                    }
                    callBtn.setEnabled(isChecked);
                    bindBtn.setChecked(isChecked);
                }
    
            });
            callBtn = (Button) findViewById(R.id.callBtn);
            callBtn.setOnClickListener(new OnClickListener() {
                
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    callService();
                }
            });
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
    
        private void callService() {
                try {
                    Person person = new Person();
                    person.setAge(22);
                    person.setName("VIJAY");
                    String response = stockService.getQuote("ANDROID",person);
                    Toast.makeText(this, "Value from service is "+response, Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
    
        private ServiceConnection serConn = new ServiceConnection() {
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                // TODO Auto-generated method stub
                Log.e(TAG, "onServiceDisconnected() called");
                bindBtn.setChecked(false);
                callBtn.setEnabled(false);
                stockService = null;
            }
    
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                // TODO Auto-generated method stub
                Log.e(TAG, "onServiceConnected() called");
                stockService = IStockQuoteService.Stub.asInterface(service);
                bindBtn.setChecked(true);
                callBtn.setEnabled(true);
            }
        };
    
        @Override
        protected void onDestroy() {
            Log.e(TAG, "onDestroy() called");
            if(callBtn.isEnabled())
                unbindService(serConn);
            super.onDestroy();
        }
    
    }

    这里介绍一下AIDL对非原句类型的支持

    1、AIDL支持String和CharSequence

    2、AIDL支持传递其他AIDL接口,但你引用的每个AIDL接口都需要一个Import语句

    3、AIDL支持传递实现android.os.Parcelable接口的复杂类型。需要在AIDL文件中包含针对这些类型的import语句

    4、AIDL支持java.util.List和java.util.Map,但具有一些限制。集合中的允许数据类型有Java原句、String、CharSequence以及android.os.Parcelable。无需为List或Map提供import语句,但需要为Parcelable提供import语句

    5、除字符串外,非原句类型需要一个方向指示符。方向指示符包括in、out和inout

  • 相关阅读:
    SignalR 持久链接 (该功能为手机设备与后台同个用户id进行实现的,仅用signalR学习参考)
    SQL SERVER 分割符转列
    js时间计算加减
    SQL查询历史执行语句
    MSSQL 多行数据串联字符分割单行
    居于HttpWebRequest的HTTP GET/POST请求
    硬件UDP读数AsynUdpClient
    SQL取分组数据的所有第一条数据
    Python 文件的使用
    Python 数据类型
  • 原文地址:https://www.cnblogs.com/vijay/p/3535932.html
Copyright © 2011-2022 走看看