您的位置:首页 > 移动开发 > Android开发

Android:AIDL创建Service

2014-08-28 23:22 465 查看
简述:

1. Android开发中会用到Service这个类,Service用于实现进程间方法的调用,UI中调用音乐播放服务就用到Service,起到跨进程通信的作用

2. AIDL: Android Interface Definition Language,Android内部进程通信接口的描述语言,通过他可以定义进程间通信接口,结合service在后台运作,暴露接口用来和当前程序通信

3,.Android 提供了Parcel类型,Parcel用作封装数据的容器,封装后的数据可以通过Intent或IPC传递,除了基本类型之外,只有实现了Parcelable接口的类才能被放入Parcel

本文参考:

http://blog.csdn.net/stonecao/article/details/6425019

http://blog.csdn.net/liuhe688/article/details/6409708

http://blog.sina.com.cn/s/blog_78e3ae430100pxba.html

知识点:

1. Android service

2. AIDL的使用,在aidl文件中复杂类型的导入

3. Parcelable接口的使用

项目工程文件目录

其中gen下的com.atp.aidl是AIDL自带生成的(clean->build之后就能生成)



代码:

com.atp.aidl包

Fruit.java

[java] view
plaincopy

package com.atp.aidl;



import android.os.Parcel;

import android.os.Parcelable;



public class Fruit implements Parcelable {

private String name;

private Integer size;

public Fruit(String name, Integer size) {

this.name = name;

this.size = size;

}



public Fruit(Parcel source) {

readFromParcel(source);

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Integer getsize() {

return size;

}

public void setsize(Integer size) {

this.size = size;

}

@Override

public String toString() {

return "[name: " + name + ", size: " + size + "]";

}





//AIDL needs CREATOR static final android.os.Parcelable.Creator<T> to call service

public static final Parcelable.Creator<Fruit> CREATOR = new Parcelable.Creator<Fruit>() {

@Override

public Fruit createFromParcel(Parcel source) {

return new Fruit(source);

}



@Override

public Fruit[] newArray(int size) {

return new Fruit[size];

}

};



@Override

public int describeContents() {

return 0;

}



//write and read must in the same sequence

@Override

public void writeToParcel(Parcel dest, int flags) {

dest.writeString(name);

dest.writeInt(size);

}



public void readFromParcel(Parcel source) {

name = source.readString();

size = source.readInt();

}

}

Fruit.aidl 复杂类型的aidl文件

[plain] view
plaincopy

package com.atp.aidl;

parcelable Fruit;

ITestService.aidl的接口文件

[plain] view
plaincopy

package com.atp.aidl;



import com.atp.aidl.Fruit;



interface ITestService {

String getSomething();

Fruit getFruit();

}

com.atp.service包

[java] view
plaincopy

package com.atp.service;



import com.atp.aidl.Fruit;

import com.atp.aidl.ITestService;



import android.app.Service;

import android.content.Intent;

import android.os.IBinder;

import android.os.RemoteException;

import android.util.Log;





public class MyService extends Service{

public static final String TAG = "com.atp.ui.MyService";



private class MyServiceImpl extends ITestService.Stub{



@Override

public String getSomething() throws RemoteException {

Log.e(TAG, "getSomething");

return "Apple";

}



@Override

public Fruit getFruit() throws RemoteException {

Fruit fruit = new Fruit("Banana", 10);

return fruit;

}



}



@Override

public IBinder onBind(Intent arg0) {

//return implementation of AIDL

return new MyServiceImpl();

}



@Override

public void onDestroy() {

Log.e(TAG, "Release MyService");

super.onDestroy();

}

}

com.atp.ui包

MainActivity.java

[java] view
plaincopy

package com.atp.ui;



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.TextView;



import com.atp.R;

import com.atp.aidl.Fruit;

import com.atp.aidl.ITestService;

import com.atp.service.MyService;



public class MainActivity extends Activity {

public static final String TAG = "com.atp.ui.MainActivity";



private Button myBtn = null;

private TextView myTv = null;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main_activity);

myBtn = (Button) findViewById(R.id.myBtn);

myTv = (TextView) findViewById(R.id.myTv);

myBtn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View arg0) {

bindMyService();

}

});

}



private ITestService iService = null;

private ServiceConnection conn = new ServiceConnection(){

private String resultFromService;

private Fruit fruitFromService;

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

//return AIDL object,then call methods of AIDL

iService = ITestService.Stub.asInterface(service);

try {

resultFromService = iService.getSomething();

fruitFromService = iService.getFruit();

} catch (RemoteException e) {

Log.e(TAG, "Error while call on iService!");

e.printStackTrace();

}

Log.e(TAG, "something is:" + resultFromService);

myTv.setText("something is:" + resultFromService + "\n"

+ "fruit: " + fruitFromService.toString());

}



@Override

public void onServiceDisconnected(ComponentName arg0) {

Log.i(TAG, "release iService");

}

};





private void bindMyService(){

Intent intent = new Intent(this, MyService.class);

startService(intent);

bindService(intent, conn, Context.BIND_AUTO_CREATE);

}

}

视图xml文件

main_activity.xml

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/mainRelativeLayout"

android:layout_width="match_parent"

android:layout_height="match_parent"

>



<Button

android:id="@+id/myBtn"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Start"

android:textSize="22dip"

/>



<TextView

android:id="@+id/myTv"

android:layout_width="500dip"

android:layout_height="100dip"

android:layout_below="@id/myBtn"

android:text="Text Area"

android:textSize="22dip"/>



</RelativeLayout>

下面是在AndroidManifest.xml注册这个service

其中对于android:process这一属性的解释:

android:process=":remote",代表在应用程序里,当需要该service时,会自动创建新的进程。而如果是android:process="remote",没有“:”分号的,则创建全局进程,不同的应用程序共享该进程。

AndroidManifest.xml

[html] view
plaincopy

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.atp"

android:versionCode="1"

android:versionName="1.0" >



<uses-sdk

android:minSdkVersion="8"

android:targetSdkVersion="21" />



<application

android:allowBackup="true"

android:icon="@drawable/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme" >

<activity

android:name=".ui.MainActivity"

android:label="@string/app_name" >

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

<service

android:name=".service.MyService"

android:process=":remote">

<intent-filter>

<action android:name=".aidl.ITestService" />

</intent-filter>

</service>

</application>



</manifest>

这是由com.atp.aidl下的aidl文件自动generate出来的文件

ITestService.java

[java] view
plaincopy

/*

* This file is auto-generated. DO NOT MODIFY.

* Original file: C:\\Users\\anialy.anialy-PC\\Desktop\\eclipse_work_space_2\\AndroidTestProject\\src\\com\\atp\\aidl\\ITestService.aidl

*/

package com.atp.aidl;

public interface ITestService extends android.os.IInterface

{

/** Local-side IPC implementation stub class. */

public static abstract class Stub extends android.os.Binder implements com.atp.aidl.ITestService

{

private static final java.lang.String DESCRIPTOR = "com.atp.aidl.ITestService";

/** Construct the stub at attach it to the interface. */

public Stub()

{

this.attachInterface(this, DESCRIPTOR);

}

/**

* Cast an IBinder object into an com.atp.aidl.ITestService interface,

* generating a proxy if needed.

*/

public static com.atp.aidl.ITestService asInterface(android.os.IBinder obj)

{

if ((obj==null)) {

return null;

}

android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);

if (((iin!=null)&&(iin instanceof com.atp.aidl.ITestService))) {

return ((com.atp.aidl.ITestService)iin);

}

return new com.atp.aidl.ITestService.Stub.Proxy(obj);

}

@Override public android.os.IBinder asBinder()

{

return this;

}

@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException

{

switch (code)

{

case INTERFACE_TRANSACTION:

{

reply.writeString(DESCRIPTOR);

return true;

}

case TRANSACTION_getSomething:

{

data.enforceInterface(DESCRIPTOR);

java.lang.String _result = this.getSomething();

reply.writeNoException();

reply.writeString(_result);

return true;

}

case TRANSACTION_getFruit:

{

data.enforceInterface(DESCRIPTOR);

com.atp.aidl.Fruit _result = this.getFruit();

reply.writeNoException();

if ((_result!=null)) {

reply.writeInt(1);

_result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);

}

else {

reply.writeInt(0);

}

return true;

}

}

return super.onTransact(code, data, reply, flags);

}

private static class Proxy implements com.atp.aidl.ITestService

{

private android.os.IBinder mRemote;

Proxy(android.os.IBinder remote)

{

mRemote = remote;

}

@Override public android.os.IBinder asBinder()

{

return mRemote;

}

public java.lang.String getInterfaceDescriptor()

{

return DESCRIPTOR;

}

@Override public java.lang.String getSomething() throws android.os.RemoteException

{

android.os.Parcel _data = android.os.Parcel.obtain();

android.os.Parcel _reply = android.os.Parcel.obtain();

java.lang.String _result;

try {

_data.writeInterfaceToken(DESCRIPTOR);

mRemote.transact(Stub.TRANSACTION_getSomething, _data, _reply, 0);

_reply.readException();

_result = _reply.readString();

}

finally {

_reply.recycle();

_data.recycle();

}

return _result;

}

@Override public com.atp.aidl.Fruit getFruit() throws android.os.RemoteException

{

android.os.Parcel _data = android.os.Parcel.obtain();

android.os.Parcel _reply = android.os.Parcel.obtain();

com.atp.aidl.Fruit _result;

try {

_data.writeInterfaceToken(DESCRIPTOR);

mRemote.transact(Stub.TRANSACTION_getFruit, _data, _reply, 0);

_reply.readException();

if ((0!=_reply.readInt())) {

_result = com.atp.aidl.Fruit.CREATOR.createFromParcel(_reply);

}

else {

_result = null;

}

}

finally {

_reply.recycle();

_data.recycle();

}

return _result;

}

}

static final int TRANSACTION_getSomething = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);

static final int TRANSACTION_getFruit = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);

}

public java.lang.String getSomething() throws android.os.RemoteException;

public com.atp.aidl.Fruit getFruit() throws android.os.RemoteException;

}

效果,点击之后获取service中的方法,返回所需的数据:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: