• android开发系列之aidl


          aidl在android开发中的主要作用就是跨进程通讯来着,说到进程相比很多人都是非常熟悉了,但是为什么会有跨进程通讯这个概念呢?原来在android系统中,有这么一套安全机制,为了各个Apk数据的独立性、安全性,它们彼此之间是不能直接进行数据的访问的。所以为了实现多个APK之间的数据、方法、代码复用,我们通常采用的做法就是定义好AIDL接口,这样就能够既保护现有代码的逻辑性、同时又能够兼顾好封装性,各个团队之间只需要沟通好AIDL接口定义就可以了。

          下面让我们直接进入主题吧,在进行AIDL定义的时候,通常会将公用的代码逻辑单独封装到一个独立的APK中,这个APK我们不妨成为服务器Server。当定义好Server断逻辑之后,就可以供其他第三方代码调用了,这个第三方Apk我们不妨成为Client。但是Server和Client方,必须同时保证AIDL文件名称相同,同时又在相同的包名下面。只有同时满足这两点的话,才能利用AIDL进行通讯。

          假如有一套公用的计算方法,在多个第三方APK中都需要调用。所以定义两个android project,一个服务端程序AidlServer,一个客户端测试程序TestClient。其中服务端、客户端的AIDL接口文件都位于包“com.example.aidl下面”,定义好ICal.aidl文件,代码如下:

    package com.example.aidl;
    
    interface ICal{
        double doCal(double x,double y);
    }
    

     在定义书写aidl文件代码的时候,语法规则跟java一致,切记不要忘记引入package或者少写了分号。当定义好aidl文件之后,并且没有错误的情况下,按住ctrl+s键保存编译,会发现项目的gen文件夹下面会自动生成一个同名的java文件。如果到这一步正确的生成了java文件的话,那么说明服务端,客户端的AIDL接口部分已经定义完成,那么接下来怎么将服务端的接口暴露给客户端调用呢?答案是通过service,我们先来看一下service端的CalService代码:

    package com.example.service;
    
    import com.example.aidl.ICal;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.util.Log;
    
    public class CalService extends Service {
    
    	private static final String TAG = CalService.class.getName();
    
    	@Override
    	public IBinder onBind(Intent intent) {
    		return mBinder;
    	}
    
    	@Override
    	public void onCreate() {
    		Log.d(TAG,"onCreate action");
    		super.onCreate();
    	}
    
    	@Override
    	public void onStart(Intent intent, int startId) {
    		Log.d(TAG, "onStart action");
    		super.onStart(intent, startId);
    	}
    
    	@Override
    	public void onDestroy() {
    		Log.d(TAG, "onDestroy");
    		super.onDestroy();
    	}
    
    	@Override
    	public boolean onUnbind(Intent intent) {
    		Log.d(TAG, "onUnbind");
    		return super.onUnbind(intent);
    	}
    	
    	private final ICal.Stub mBinder=new ICal.Stub() {
    		
    		@Override
    		public double doCal(double x, double y) throws RemoteException {
    			CalUtils calUtils=new CalUtils();
    			double result=calUtils.add(x, y);
    			return result;
    		}
    	};
    	
    }
    

     通过CalService可以很好的暴露CalUtils公用类里面的计算方法,CalUtils代码如下:

    package com.example.service;
    
    public class CalUtils{
    
          public double add(double x,double y){
                return x+y;
          }
    }
    

     最后还需要在AndroidManifest.xml文件里面注册CalService,代码如下:

    <service 
          android:name="com.example.service.CalService">
         <intent-filter>
             <action android:name="com.example.service.CalService"/>
         </intent-filter>
    </service>
    

          到这里,服务器端的代码逻辑就完了,下面开始Client的测试代码编写。首先定义好一个计算xml页面,里面放置两个EditText、一个TextView、一个Button、一个TextView,这块的xml代码就不放出来了,稍后demo里面有。主要来看看后台的Activity代码,如下:

    package com.example.mytestpro;
    
    import com.example.aidl.ICal;
    
    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.graphics.Color;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    
    public class CalActivity extends Activity implements OnClickListener {
    
    	private static final String TAG=CalActivity.class.getName();
    	
    	private EditText etX,etY;
    	private Button btnCal;
    	private TextView tvInfo;
    	private ICal mService;
    	
    	private ServiceConnection mServiceConnection=new ServiceConnection() {
    		
    		@Override
    		public void onServiceDisconnected(ComponentName name) {
    			Log.d(TAG, "do Disconnected action");
    			mService=null;
    		}
    		
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service) {
    			Log.d(TAG, "do Connected action");
    			mService=ICal.Stub.asInterface(service);
    		}
    	};
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_calctivity);
    		
    		initView();
    		setClick();
    		startBindServiceAction();
    	}
    	
    	private void startBindServiceAction(){
    		Bundle args=new Bundle();
    		Intent intent=new Intent("com.example.service.CalService");
    		intent.setPackage("com.example.aidlserver");
    		intent.putExtras(args);
    		bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
    	}
    	
    	private void initView(){
    		etX=(EditText)findViewById(R.id.etX);
    		etY=(EditText)findViewById(R.id.etY);
    		btnCal=(Button)findViewById(R.id.btnCal);
    		tvInfo=(TextView)findViewById(R.id.tvInfo);
    	}
    	
    	private void setClick(){
    		btnCal.setOnClickListener(this);
    	}
    
    	@Override
    	public void onClick(View v) {
    		switch (v.getId()) {
    		case R.id.btnCal:
    			excuteCalAction();
    			break;
    
    		default:
    			break;
    		}
    	}
    	
    	private void excuteCalAction(){
    		try {
    			double x=Double.parseDouble(etX.getText().toString());
    			double y=Double.parseDouble(etY.getText().toString());
    			String result="result:"+mService.doCal(x, y);
    			tvInfo.setText(result);
    			tvInfo.setTextColor(Color.RED);
    		} catch (Exception e) {
    			Log.d(TAG, e.getMessage());
    		}
    	}
    }
    

           有兴趣的读者,可点击下载服务端demo客户端demo

  • 相关阅读:
    一只特立独行的猪
    每天写出好代码的5个建议
    电脑修好了
    VB编程修改AutoCAD长度型尺寸标注
    前天我放学回家
    VB编程修改AutoCAD坐标型尺寸标注
    VB编程操作AutoCAD尺寸标注样式
    这是一个错误的程序
    2011年6月27日星期二
    2011年6月20日星期一
  • 原文地址:https://www.cnblogs.com/xiaocai20091687/p/xiacai_android_17.html
Copyright © 2020-2023  润新知