• android 之 AIDL


    AIDL (android interface defintion language)  定义跨进程调用数据,也就是说不同进程之间的数据共享。

    • AIDL 定义接口的源代码必须以.aidl结尾。
    • AIDL 接口中用到的数据类型,除了基本类型、String List Map CharSequence 之外,其他类型都需要导包。
    先看一下项目结构图:


    接下来我们需要定义一个Book实体,属于自定义类型。
    Book.java
    package com.hkrt.action;
    import android.os.Parcel;
    import android.os.Parcelable;
    
    public class Book implements Parcelable {
    	private String author;
    	private String bookName;
    	private int bookPrice;
    
    	public Book() {
    	}
    	public Book(Parcel parcel) {
    		author = parcel.readString();
    		bookName = parcel.readString();
    		bookPrice = parcel.readInt();
    	}
    	public String getBookName() {
    		return bookName;
    	}
    	public void setBookName(String bookName) {
    		this.bookName = bookName;
    	}
    	public int getBookPrice() {
    		return bookPrice;
    	}
    	public void setBookPrice(int bookPrice) {
    		this.bookPrice = bookPrice;
    	}
    	public String getAuthor() {
    		return author;
    	}
    	public void setAuthor(String author) {
    		this.author = author;
    	}
    
    	@Override
    	public int describeContents() {
    		return 0;
    	}
    	@Override
    	public void writeToParcel(Parcel parcel, int flags) {
    		  parcel.writeString(author);
    		  parcel.writeString(bookName);  
    	      parcel.writeInt(bookPrice); 
    	    
    	}
    
    	public static final Parcelable.Creator<Book> CREATOR = new Creator<Book>() {
    		public Book createFromParcel(Parcel source) {
    			return new Book(source);
    		}
    		public Book[] newArray(int size) {
    			return new Book[size];
    		}
    	
    	}; 
    }
    
    注:对象在跨进程访问,类必须实现 Parcelable。原文是这样说的。
    Interface for classes whose instances can be written to and restored from a Parcel. Classes implementing the Parcelable interface must also have a static field called CREATOR, which is an object implementing the Parcelable.Creator interface.
    然后定义一个Book.aidl 文件
    parcelable Book;  
    
    接下来定义把对外提供的服务定义aidl(IaidlServerService.aidl)。
    package com.hkrt.action;
    import com.hkrt.action.Book; 
    import java.util.List;
    interface IAIDLServerService {   
          
        String sayHello();  
          
        Book getBook(); 
        
       List<Book> getBooks();
       
    } 
    当保存这个文件时,就会在gen/<package>/生成对应的java文件。如图上所示。
    然后。编写本地实现,实现这三个接口,并初始化数据。

    package com.hkrt.action;
    
    import java.util.ArrayList;
    import java.util.List;
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.os.RemoteException;
    import com.hkrt.action.IAIDLServerService.Stub;
    public class AidlServerService extends Service{
    	 @Override  
    	    public IBinder onBind(Intent intent) {  
    	        return mBinder;  
    	    }  
    	    /*** 在AIDL文件中定义的接口实现 */   
        private IAIDLServerService.Stub mBinder = new Stub() {  
        	@Override
            public String sayHello() throws RemoteException {  
                return "Hello";  
            }
        	@Override
            public Book getBook() throws RemoteException {  
                Book mBook = new Book();  
                mBook.setAuthor("机器人");
                mBook.setBookName("Android应用开发");  
                mBook.setBookPrice(50);  
                return mBook;  
            }
    
    		@Override
    		public List<Book> getBooks() throws RemoteException {
    			 List<Book> books = new ArrayList<Book>();
    		      Book book1 = new Book();  
    		      book1.setAuthor("机器人Tom");
    		      book1.setBookName("Android adil person one");  
    		      book1.setBookPrice(501);
                  books.add(book1);
                  Book book2 = new Book();  
                  book2.setAuthor("机器人Jom");
                  book2.setBookName("Android adil person two");  
                  book2.setBookPrice(502);
                  books.add(book2);
                  Book book3 = new Book();  
                  book3.setAuthor("机器人Jom3");
                  book3.setBookName("Android adil person three");  
                  book3.setBookPrice(502);
                  books.add(book3);
    			return books;
    		}  
            
        };  
    
    }
    
    需要把这个service 注册到AndroidManifest.xml下。

     <service android:name="AidlServerService"   android:process=":remote">  
                <intent-filter>  
                    <action android:name="com.hkrt.action.IAIDLServerService"></action>  
                </intent-filter>  
            </service>  

    这样第一个应用就写完了,只是提供一些数据,可又被另一个进程访问。
    接下来我们需要新建另外一个程序,访问第一个程序对外提供的数据。
    先看一下结构图:


    具中图:

    是从第一个图中拷出来的。自动就会在gen下对应的java文件。

    我们先定义一下main.xml中的布局文件如下。
    <?xml version="1.0" encoding="utf-8"?>  
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
        android:orientation="vertical"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
        >  
    <TextView    
        android:id="@+id/textview"  
        android:layout_width="200dp"   
        android:layout_height="20dp"   
        android:text="@string/hello"  
        />  
    <Button  
        android:id="@+id/button"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:text="调用AIDL服务"  
        />  
            <ExpandableListView 
        	android:id="@+id/ExpandableListView01"  
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent">
            </ExpandableListView>  
    </LinearLayout>
    效果图:

    接下来,我们需要把第一个程序对外程序提供的内容展出来。
    我把第一个程序对处提供的集合用树结构展示出来。
    TreeViewAdapter.java 是为树结构准备的。
    package com.hkrt;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.content.Context;
    import android.view.Gravity;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.AbsListView;
    import android.widget.BaseExpandableListAdapter;
    import android.widget.TextView;
    
    public class TreeViewAdapter extends BaseExpandableListAdapter {
    	public static final int ItemHeight = 48;// 每项的高度
    	public static final int PaddingLeft = 36;// 每项的高度
    	private int myPaddingLeft = 0;// 如果是由SuperTreeView调用,则作为子项需要往右移
    
    	static public class TreeNode {
    		Object parent;
    		List<Object> childs = new ArrayList<Object>();
    	}
    
    	List<TreeNode> treeNodes = new ArrayList<TreeNode>();
    	Context parentContext;
    
    	public TreeViewAdapter(Context view, int myPaddingLeft) {
    		parentContext = view;
    		this.myPaddingLeft = myPaddingLeft;
    	}
    
    	public List<TreeNode> GetTreeNode() {
    		return treeNodes;
    	}
    
    	public void UpdateTreeNode(List<TreeNode> nodes) {
    		treeNodes = nodes;
    	}
    
    	public void RemoveAll() {
    		treeNodes.clear();
    	}
    
    	public Object getChild(int groupPosition, int childPosition) {
    		return treeNodes.get(groupPosition).childs.get(childPosition);
    	}
    
    	public int getChildrenCount(int groupPosition) {
    		return treeNodes.get(groupPosition).childs.size();
    	}
    
    	static public TextView getTextView(Context context) {
    		AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
    				ViewGroup.LayoutParams.FILL_PARENT, ItemHeight);
    
    		TextView textView = new TextView(context);
    		textView.setLayoutParams(lp);
    		textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
    		return textView;
    	}
    
    	public View getChildView(int groupPosition, int childPosition,
    			boolean isLastChild, View convertView, ViewGroup parent) {
    		TextView textView = getTextView(this.parentContext);
    		textView.setText(getChild(groupPosition, childPosition).toString());
    		textView.setPadding(myPaddingLeft + PaddingLeft, 0, 0, 0);
    		return textView;
    	}
    
    	public View getGroupView(int groupPosition, boolean isExpanded,
    			View convertView, ViewGroup parent) {
    		TextView textView = getTextView(this.parentContext);
    		textView.setText(getGroup(groupPosition).toString());
    		textView.setPadding(myPaddingLeft + (PaddingLeft >> 1), 0, 0, 0);
    		return textView;
    	}
    
    	public long getChildId(int groupPosition, int childPosition) {
    		return childPosition;
    	}
    
    	public Object getGroup(int groupPosition) {
    		return treeNodes.get(groupPosition).parent;
    	}
    
    	public int getGroupCount() {
    		return treeNodes.size();
    	}
    
    	public long getGroupId(int groupPosition) {
    		return groupPosition;
    	}
    
    	public boolean isChildSelectable(int groupPosition, int childPosition) {
    		return true;
    	}
    
    	public boolean hasStableIds() {
    		return true;
    	}
    }
    

    最后主要的展示 AidlClientDemoActivity.java 代码
    package com.hkrt;
    
    import java.util.List;
    
    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.os.RemoteException;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.ExpandableListView;
    import android.widget.TextView;
    import android.widget.Toast;
    import android.widget.ExpandableListView.OnChildClickListener;
    
    import com.hkrt.action.Book;
    import com.hkrt.action.IAIDLServerService;
    
    public class AidlClientDemoActivity extends Activity {
    	    private TextView mTextView;  
    	    private Button mButton;  
    	    
    	    ExpandableListView expandableList;  
    	    TreeViewAdapter adapter;  
    	    public String[] groups ;  
    	    public String[][]  child;
    	      
    	    private IAIDLServerService mIaidlServerService = null;  
    	      
    	    private ServiceConnection mConnection = new ServiceConnection() {  
    	          
    	        public void onServiceDisconnected(ComponentName name) {  
    	            mIaidlServerService = null;  
    	        }     
    	        public void onServiceConnected(ComponentName name, IBinder service) {  
    	            mIaidlServerService = IAIDLServerService.Stub.asInterface(service);  
    	            //aidl通信  
    	            try {  
    	                String mText = "Say hello: " + mIaidlServerService.sayHello() + "\n"; 
    	                mText += "作者: " + mIaidlServerService.getBook().getAuthor()+"\n";  
    	                mText += "书名: " + mIaidlServerService.getBook().getBookName()+"\n";  
    	                mText += "价格: " + mIaidlServerService.getBook().getBookPrice();  
    	                List<Book> books =  mIaidlServerService.getBooks();
    	            	groups = new String[books.size()];
    	                for(int i=0;i<books.size();i++){
    	                	groups[i]=books.get(i).getBookName();
    	                }
    	                child =new String[groups.length][3];
    	                for(int j=0;j<groups.length;j++){
    	                	Book book = books.get(j);
    	                	child[j][0] = "作者: " +book.getAuthor();
    	                	child[j][1] = "书名: "+book.getBookName();
    	                	child[j][2] = "价格: "+book.getBookPrice() + "";
    	                }
    	                mTextView.setText(mText);  
    	                List<TreeViewAdapter.TreeNode> treeNode = adapter.GetTreeNode();  
    	                for(int i=0;i<groups.length;i++)  
    	                {  
    	                    TreeViewAdapter.TreeNode node=new TreeViewAdapter.TreeNode();  
    	                    node.parent=groups[i];  
    	                    for(int ii=0;ii<child[i].length;ii++)  
    	                    {  
    	                        node.childs.add(child[i][ii]);  
    	                    }  
    	                    treeNode.add(node);  
    	                }  
    	                  
    	                adapter.UpdateTreeNode(treeNode);       
    	                expandableList.setAdapter(adapter);  
    	                expandableList.setOnChildClickListener(new OnChildClickListener(){  
    	                    @Override  
    	                    public boolean onChildClick(ExpandableListView arg0, View arg1,  
    	                            int parent, int children, long arg4) {  
    	                        String str="parent id:"+String.valueOf(parent)+",children id:"+String.valueOf(children);  
    	                        Toast.makeText(AidlClientDemoActivity.this, str, 300).show();  
    	                        return false;  
    	                    }  
    	                });  
    	            } catch (RemoteException e) {  
    	                e.printStackTrace();  
    	            }  
    	            
    	        }  
    	    };  
    	      
    	    @Override  
    	    public void onCreate(Bundle savedInstanceState) {  
    	        super.onCreate(savedInstanceState);  
    	        setContentView(R.layout.main);        
    	        //初始化控件  
    	        mTextView = (TextView)findViewById(R.id.textview);  
    	        mButton = (Button)findViewById(R.id.button);  
    	        expandableList=(ExpandableListView) this.findViewById(R.id.ExpandableListView01);  
    	        //增加事件响应  
    	        mButton.setOnClickListener(new OnClickListener(){  
    	            public void onClick(View v) {  
    	                Intent service = new Intent("com.hkrt.action.IAIDLServerService");  
    	                bindService(service, mConnection,BIND_AUTO_CREATE);  
    	                adapter=new TreeViewAdapter(AidlClientDemoActivity.this,TreeViewAdapter.PaddingLeft>>1);  
    	    	        adapter.RemoveAll();  
    	                adapter.notifyDataSetChanged();  
    	            }  
    	        });  
    	    }  
    }

    效果图:


    如果。需要传递参数,服务器端的IaidlServerService.aidl
    可以定义成 String sayMe(in String str);
    in 表示传入参数。
    在aidl 中写注释     /**注释*/

  • 相关阅读:
    linux命令及相关配置
    EditPlus配置ftp连接linux
    06_事件机制
    HTTP协议简介
    Codeforces Round #691 (Div. 2) C. Row GCD (数学)
    Codeforces Round #690 (Div. 3) E2. Close Tuples (hard version) (数学,组合数)
    牛客编程巅峰赛S2第10场
    Codeforces Round #665 (Div. 2) D. Maximum Distributed Tree (dfs计数,树)
    牛客编程巅峰赛S2第7场
    Codeforces Global Round 12 D. Rating Compression (思维,双指针)
  • 原文地址:https://www.cnblogs.com/java20130726/p/3218335.html
Copyright © 2020-2023  润新知