Service bound(三)

service 绑定有三种实现方式:

1. 直接继承Binder类实现。

      条件: 同一应用,同一进程

2. 使用Messenger实现。

      条件:要在不同的进程间通信,这种方式不用考虑线程安全性。(单线程操作时使用)

3. 使用AIDL实现。

      条件:要在不同的进程间通信,并且需要多线程处理。要考虑线程之间的安全性。


使用AIDL实现:

三大基本步骤

  • 创建.aidl文件
  • 实现接口
  • 公开接口


创建.aidl文件

  • 方法定义有0个或者多个参数,可以返回一个值或者是void.
  • 方法中不是基本类型的参数,需要在方法参数前面加入in , out or inout
  • 包含在.aidl中所有的注释在IBinder接口中都会生成(除了在import和package之前的注释)
  • 仅仅支持方法,不支持静态的成员变量。
package com.hualu.servicemy;

import com.hualu.servicemy.Book;

interface IRemoteService{
	
	int getPID() ;
	
	void basicInt(int i) ;
	
	void basicByte(byte b) ;
	
	void basicLong(long l) ;
	
	void basicDouble(double d) ;
	
	void basicFloat(float f) ;
	
	void basicString(String s) ;
	
	void basicBoolean(boolean b) ;
	
	void basicCharSequence(char c) ;
	
	void basicList(inout List<String> l) ;
	
	void basicMap(in Map m) ;
	
	Book getBook() ;
	
}


实现接口

  • 不能保证是从主线程里发起的调用,因此在使用的时候,需要考虑多线程启动和保证service运行时的线程安全性。
  • 默认情况,远程调用是同步的。
  • Service不会返回任何开发者自己抛出的异常到调用者。

package com.hualu.servicemy;

import java.util.List;
import java.util.Map;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;

public class RemoteService extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		return iBinder;
	}

	private final IRemoteService.Stub iBinder = new IRemoteService.Stub() { //实现接口
		
		@Override
		public int getPID() throws RemoteException {
			return  Process.myPid();
		}
		
		@Override
		public Book getBook() throws RemoteException {
			Book book = new Book() ;
			book.setName("心善") ;
			return book;
		}
		
		@Override
		public void basicString(String s) throws RemoteException {
			System.out.println("string = "+s);
			
		}
		
		@Override
		public void basicMap(Map m) throws RemoteException {
			System.out.println("Map size = "+m.size());
			
		}
		
		@Override
		public void basicLong(long l) throws RemoteException {
			
			System.out.println("long = "+l);
		}
		
		@Override
		public void basicList(List<String> l) throws RemoteException {
			System.out.println("List size = "+l.size());
			
		}
		
		@Override
		public void basicInt(int i) throws RemoteException {
			
			System.out.println("int = "+i);
		}
		
		@Override
		public void basicFloat(float f) throws RemoteException {
			
			System.out.println("float = "+f);
		}
		
		@Override
		public void basicDouble(double d) throws RemoteException {
			
			System.out.println("double = "+d);
		}
		
		@Override
		public void basicCharSequence(char c) throws RemoteException {
			System.out.println("char = "+c);
			
		}
		
		@Override
		public void basicByte(byte b) throws RemoteException {
			
			
		}
		
		@Override
		public void basicBoolean(boolean b) throws RemoteException {
			
			
		}
	};
	
}


公开接口

package com.hualu.servicemy;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.View;
import android.view.View.OnClickListener;

import com.hualu.serviceexample.R;

public class RemoteActivity extends Activity {

	private IRemoteService  remoteService ;

	private boolean bindFlag = false ;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.remote_service) ;
		findViewById(R.id.remote).setOnClickListener(l) ;
	}
	
	private OnClickListener l = new OnClickListener(){

		@Override
		public void onClick(View v) {
			if(remoteService != null){
				try {
					remoteService.basicByte((byte)4) ;
					remoteService.basicBoolean(true) ;
					remoteService.basicInt(132) ;
					remoteService.basicLong(146) ;
					remoteService.basicFloat(83646.3f) ;
					remoteService.basicDouble(2.12) ;
					remoteService.basicString("remoteService") ;
					remoteService.basicCharSequence('r') ;
					List<String> l = new ArrayList<String>() ;
					l.add("Remote") ;
					l.add("Service") ;
					remoteService.basicList(l) ;
					Map<String,String> m = new HashMap<String,String>();
					m.put("a", "a") ;
					remoteService.basicMap(m) ;
					Book b = remoteService.getBook() ;
					System.out.println(b.getName());
				} catch (RemoteException e) {
					e.printStackTrace();
				}
				
			}
		}
		
	} ;
	
	@Override
	protected void onStart() {
		super.onStart();
		binderService() ;
	}
	
	@Override
	protected void onStop() {
		super.onStop();
		unBindService() ;
		remoteService = null ;
	}
	
	private ServiceConnection conn = new ServiceConnection(){ //公开接口

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			remoteService = IRemoteService.Stub.asInterface(service) ;
			bindFlag = true ;
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			remoteService = null ;
			bindFlag = false ;
		}
		
	} ;
	
	private void binderService(){
		bindService(new Intent(RemoteService.class.getName()), conn, Context.BIND_AUTO_CREATE) ;
	}
	
	private void unBindService(){
		unbindService(conn) ;
		bindFlag = false ;
		conn = null ;
	}
	
}






在aidl文件传递对象:

  1. 创建实现Parcelable接口的类。
  2. 实现 writeToParcel, 将对象目前的状态写到Pacel中。
  3. 增加一个名字为CREATOR的静态的成员变量,这个CREATOR实现了Parcelable.Creator接口。
  4. 最终,创建一个.aidl文件,声明你的parcelable类。
Book.aidl
package com.hualu.servicemy;

parcelable Book ;

Book.java

package com.hualu.servicemy;

import android.os.Parcel;
import android.os.Parcelable;

public class Book implements Parcelable {

	private String name ;
	
	@Override
	public int describeContents() {
		return 0;
	}
	
	public Book(){}
	
    private Book(Parcel in) {
        readFromParcel(in);
    }

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeString(name) ;
	}

	
	public void readFromParcel(Parcel in){
		name = in.readString() ;
	}
	
	
	public final static Parcelable.Creator<Book> CREATOR = new Parcelable.Creator<Book>(){

		@Override
		public Book createFromParcel(Parcel source) {
			
			return new Book(source);
		}

		@Override
		public Book[] newArray(int size) {
			
			return new Book[size];
		}
		
	} ;
	
	public void setName(String name){
		this.name = name ;
	}
	
	public String getName(){
		return this.name ;
	}
	
}

Layout文件:

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

    <Button
        android:id="@+id/remote"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/get_remote_data" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/remote_service" />

</LinearLayout>

Manifest文件中定义的Activity和service:

<activity android:name="com.hualu.servicemy.RemoteActivity">
			<intent-filter>
				<action android:name="android.intent.action.MAIN"></action>
				<category android:name="android.intent.category.LAUNCHER"></category>			
			</intent-filter>
		</activity>
        <service android:name="com.hualu.servicemy.RemoteService">
            <intent-filter >
                <action android:name="com.hualu.servicemy.RemoteService"/>
            </intent-filter>
        </service>


运行结果:




公开接口
原文地址:https://www.cnblogs.com/java20130722/p/3207348.html