zoukankan      html  css  js  c++  java
  • 安卓中AIDL的使用方法快速入门

    1.AIDL是什么?

    AIDL全称是Android Interface Definition Language,即安卓接口定义语言。

    2.AIDL是用来做什么的?(为什么要有AIDL)

    AIDL是用来进行进程间通信(IPC全称interprocess communication )的。

    3.如何使用AIDL?

    对于AIDL的使用,

    服务端需要完成的任务是:

    ①.写一个xxxx.aidl文件

    ②.写一个Service并在AndroidManifest.xml中声明它。(注意:这个service里面有一个引用了实现xxxx.Stub抽象类的IBinder对象,这个对象将在service的onBind方法里面返回给调用者)

    客户端的任务:

    ①.使用和服务端相同的那个aidl文件

    ②.在实现了ServiceConnection接口的onServiceConnected(ComponentName name, IBinder service)方法中调用myvar = testidl.Stub.asInterface(service)保存得到的对象,其中myvar是xxxx的类型

    这么说还是不够清楚,下面直接上代码。

    首先是服务端的

    //testidl.idl文件的内容
    package com.example.xxnote;
    
    interface testidl {
    	void TestFunction(int anInt, long aLong, boolean aBoolean, float aFloat,
                double aDouble, String aString);
    }
    

     

    //myaidlservice.java文件的内容
    package com.example.xxnote;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.os.RemoteException;
    
    public class myaidlservice extends Service {
    
    	private final IBinder myStub = new testidl.Stub() {
    
    		@Override
    		public void TestFunction(int anInt, long aLong, boolean aBoolean,
    				float aFloat, double aDouble, String aString)
    				throws RemoteException {
    			// TODO Auto-generated method stub
    			System.out.println("basicTypes()");
    			System.err.println("Service"+anInt + "," + aLong + "," + aBoolean + ","
    					+ aFloat + "," + aDouble + "," + aString);
    		}
    	};
    
    	@Override
    	public IBinder onBind(Intent intent) {
    		// TODO Auto-generated method stub
    		System.out.println("AIDL Service  onBind, and return IBinder");
    		return myStub;
    	}
    
    	@Override
    	public void onCreate() {
    		// TODO Auto-generated method stub
    		System.out.println("AIDL Service onCreate");
    		super.onCreate();
    	}
    
    	@Override
    	public boolean onUnbind(Intent intent) {
    		// TODO Auto-generated method stub
    		System.out.println("AIDL Service onUnbind");
    		return super.onUnbind(intent);
    	}
    
    	@Override
    	public void onDestroy() {
    		// TODO Auto-generated method stub
    		System.out.println("AIDL Service onDestroy");
    		super.onDestroy();
    	}
    
    	@Override
    	public int onStartCommand(Intent intent, int flags, int startId) {
    		// TODO Auto-generated method stub
    		System.out.println("AIDL Service onStartCommand");
    		return super.onStartCommand(intent, flags, startId);
    	}
    }
    

     

    1 <!--  AndroidManifest.xml 的 application 标签的内容-->
    2 <service android:name="myaidlservice">
    3             <intent-filter >
    4                 <action android:name="zhenshi.mafan.qisia.aidl"/>
    5             </intent-filter>
    6  </service>

     对于客户端,首先需要把aidl文件复制到相应的目录本例中是src/com/example/xxnote/testidl.aidl

    package com.example.xxnote.callaidl;
    
    import com.example.xxnote.testidl;
    
    import android.R.bool;
    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    public class MainActivity extends Activity {
    
    	private testidl mytTestidl;
    	private ServiceConnection connection;
    	private boolean isServiceConnected;
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		connection = new ServiceConnection() {
    			
    
    			@Override
    			public void onServiceDisconnected(ComponentName name) {
    				// TODO Auto-generated method stub
    				System.out.println("Client onServiceDisconnected");
    			}
    			
    			@Override
    			public void onServiceConnected(ComponentName name, IBinder service) {
    				// TODO Auto-generated method stub
    				System.out.println("Client onServiceConnected");
    				mytTestidl = testidl.Stub.asInterface(service);
    				isServiceConnected = true;
    			}
    		};
    	}
    
    	@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;
    	}
    
    	
    	@Override
    	public boolean onOptionsItemSelected(MenuItem item) {
    		// Handle action bar item clicks here. The action bar will
    		// automatically handle clicks on the Home/Up button, so long
    		// as you specify a parent activity in AndroidManifest.xml.
    		int id = item.getItemId();
    		if (id == R.id.action_settings) {
    			return true;
    		}
    		return super.onOptionsItemSelected(item);
    	}
         
            //关闭服务按钮的事件
    	public void StopMyService(View v) {
    		System.out.println("StopMyService");
    		isServiceConnected = false;
    		unbindService(connection);
    		mytTestidl = null;
    	}
         //开启服务按钮的事件
    	public void StartMyService(View v) {
    		System.out.println("before bindService()");
    		bindService(
    				new Intent().setAction("zhenshi.mafan.qisia.aidl"), 
    				connection,
    				Context.BIND_AUTO_CREATE);
    		/**
    		 * bindService是异步的所以执行bindService方法的同时也开始执行下面的方法了,
    		 * Debug跟踪了一下程序发现貌似Activity里面所有的方法都是在主线程的loop()方法
    		 * 循环里面以消息队列里面的一个消息的样子执行的,也就是此处的StartMyService方
    		 * 法对应的消息处理完(此函数返回)后,才能处理下一个消息,即执行onServiceConnected回调方法
    		 * 
    		 * 试验了一下,StopMyService里面把mytTestidl赋值为null,即每次解除服务绑定后都重置mytTestidl为null
    		 * 果然每次下面的语句:
    		 * mytTestidl.basicTypes(1, 1, true, 100.0f, 200.0, "ssss");
    		 * 都报空指针异常
    		 */
    		
    		try {
    			mytTestidl.TestFunction(1, 1, true, 100.0f, 200.0, "ssss");
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    }
    

      

    这里还有一个需要注意的地方,就是bindService方法 的时候用到的intent,通过setAction可以成功启动服务,用setClassName就不能,不知道什么原因,暂时留待以后解决。

    找到原因了,用setClassName的时候必须使用全限定类名,如:new Intent().setClassName("com.example.client.callaidl", "com.example.client.callaidl.testact")

     

     

  • 相关阅读:
    杭电 Problem
    杭电Problem 5053 the sum of cube 【数学公式】
    杭电 Problem 2089 不要62 【打表】
    杭电 Problem 4548 美素数【打表】
    杭电 Problem 2008 分拆素数和 【打表】
    杭电 Problem 1722 Cake 【gcd】
    杭电 Problem 2187 悼念512汶川大地震遇难同胞——老人是真饿了【贪心】
    杭电Problem 1872 稳定排序
    杭电 Problem 1753 大明A+B
    东北林业大 564 汉诺塔
  • 原文地址:https://www.cnblogs.com/xxNote/p/5496156.html
Copyright © 2011-2022 走看看