zoukankan      html  css  js  c++  java
  • 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>


    运行结果:




    公开接口
  • 相关阅读:
    HTML5来了,7个混合式移动开发框架
    React Native
    Cordova
    Java Next: Groovy、Scala or Clojure?
    分页 Database Frist
    Kindeditor编译器
    sql内连接
    layer删除
    实现用户注册,要求输入用户名之后,焦点离开判断用户名是否存在,如果存在给出提示,不存在允许注册改用户。要求使用AJAX
    实现根据用户名查询用户信息,要求用AJAX
  • 原文地址:https://www.cnblogs.com/java20130722/p/3207348.html
Copyright © 2011-2022 走看看