现在的位置: 首页 > 综合 > 正文

AIDL服务——传递简单类型

2013年08月15日 ⁄ 综合 ⁄ 共 4403字 ⁄ 字号 评论关闭

在android中要构建远程(不同进程之间)服务,需要使用AIDL实现

一,服务端:

1,AIDL定义:AIDL定义之后,编译器会自动在R文件中生成AIDL的java文件

package com.cjf.stock1;

interface IStockQuoteService {
	
	double getQuote(String ticker);

}

2,实现AIDL接口

package com.cjf.stock1;

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

//服务类继承必须SERVICE
public class StockQuoteService extends Service {
	private static final String TAG = "StockQuoteService";
	
	//实现AIDL(IStockQuoteService.Stub)接口,此类充当着远程服务的实现,并且onBind()方法返回此类的实例
	public class StockQuoteServiceImpl extends IStockQuoteService.Stub{

		public double getQuote(String ticker) throws RemoteException {
			
			Log.i(TAG, "getQuote() called for " + ticker);
			return 20.0;
		}
		
	}

	//在onCreate()之后被调用
	@Override
	public IBinder onBind(Intent intent) {
		
		Log.i(TAG, "onBind() called ");
		return new StockQuoteServiceImpl();//返回AIDL的一个实例
	}

	//当绑定服务时,此方法首先被调用,做一些初始化工作,(每次绑定都会被调用)
	@Override
	public void onCreate() {
		
		super.onCreate();
		Log.i(TAG, "onCreate() called ");
	}

	//解除绑定时,此方法会被调用
	@Override
	public void onDestroy() {
		
		Log.i(TAG, "onDestory() called ");
		super.onDestroy();
	}
	
	
	
	

}

3,描述文件androidmanifest.xml声明

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.cjf.stock1"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <service android:name=".StockQuoteService">
            <intent-filter>
                <!-- 为希望公开的服务接口添加filter -->
                <action android:name="com.cjf.stock1.IStockQuoteService"/>
            </intent-filter>
        </service>
    </application>

</manifest>

二,客户端

从客户端应用程序调用服务,注意在客户端项目中必须复制服务端的AIDL接口文件,且包名与服务端需保持一致。

1,main.xml布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
    <ToggleButton 
        android:id="@+id/bindBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textOn="Bind"
        android:textOff="Unbind"
        android:onClick="doClick"
        />
    <Button 
        android:id="@+id/callBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="call service"
        android:enabled="false"
        android:onClick="doClick"/>

</LinearLayout>

2,MainActivity

package com.cjf.client1;

import com.cjf.stock1.IStockQuoteService;
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.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import android.widget.ToggleButton;

//客户端复制服务端的AIDL文件,且AIDL文件的包名必须和服务端相同
public class MainActivity extends Activity {
	private static final String TAG = "MainActivity";
	private IStockQuoteService stockService = null;
	private ToggleButton bindBtn;
	private Button callBtn;
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        bindBtn = (ToggleButton) this.findViewById(R.id.bindBtn);
        callBtn = (Button) this.findViewById(R.id.callBtn);
    }
	
	public void doClick(View v){
		switch(v.getId()){
		case R.id.bindBtn:
			if(((ToggleButton)v).isChecked()){
				//属于异步调用
				bindService(new Intent(IStockQuoteService.class.getName()),//AIDL服务的名称
										serConn,//链接的一个实例
										Context.BIND_AUTO_CREATE);//自动创建服务的标识
				
			}else{
				unbindService(serConn);
				callBtn.setEnabled(false);
			}
			break;
		case R.id.callBtn:
			callService();//调用服务
			break;
		}
	}
	
	//调用服务的方法
	private void callService(){
		try {
			double val = stockService.getQuote("ANDROID");
			Toast.makeText(this, "value from service is " + val, Toast.LENGTH_LONG).show();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//绑定和解除服务时需使用此对象(服务链接对象)
	private  ServiceConnection serConn = new ServiceConnection(){

		//链接成功时调用
		public void onServiceConnected(ComponentName name, IBinder service) {
			Log.i(TAG, "onServiceConnected called ");
			stockService = IStockQuoteService.Stub.asInterface(service);//得到AIDL的一个引用
			bindBtn.setChecked(true);//选中状态
			callBtn.setEnabled(true);//可用状态
			
		}

		//服务崩溃时自动调用
		public void onServiceDisconnected(ComponentName name) {
			Log.i(TAG, "onServiceDisconnected called ");
			bindBtn.setChecked(false);//选中状态
			callBtn.setEnabled(false);//可用状态
			stockService = null;
			
		}};
		
	@Override
	protected void onDestroy() {
		Log.i(TAG, "onDestroy() called ");
		if(callBtn.isEnabled()){
			unbindService(serConn);
		}
		super.onDestroy();
	}
		
		
}

点击Bind按钮时:

抱歉!评论已关闭.