Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android初級教程進程間的通信AIDL

Android初級教程進程間的通信AIDL

編輯:關於Android編程

在介紹跨程序進程間通信AIDL前,先看一下本程序activity與某個服務是怎麼綁定在一起進行交互的。

需求:服務有兩個方法。分別是播放音樂與停止播放音樂。該程序的活動要訪問這兩個方法,在activity中控制服務的這兩個方法,通過點擊按鈕的方式實現停止與播放音樂。

對同一個程序服務與活動交互的方式,先給出一張圖片:

\

給出代碼(案例為模擬音樂播放器):

一、定義一個服務類MusicService:

 

package com.ydl.music;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

public class MusicService extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return new MusicController();// 把中間人對象返回給綁定服務方法。
	}

	class MusicController extends Binder implements MusicInterface {// 實現接口是為了讓綁定的而活動僅僅調用相應的方法
		// 比如本服務還有一個打麻將方法,不想被活動調用。則抽取接口指定訪問的方法。
		// 中間人裡面有兩個方法可以訪問到本服務中的停止和播放方法
		public void play() {
			MusicService.this.play();
		}

		public void pause() {
			MusicService.this.pause();
		}

		public void daMaJiang() {
			System.out.println("陪領導打麻將");
		}
	}

	// 本程序有兩個方法
	public void play() {
		System.out.println("播放音樂");
	}

	public void pause() {
		System.out.println("停止播放音樂");
	}
}

二、抽取interface接口:

 

 

package com.ydl.music;

public interface MusicInterface {
	void play();

	void pause();
}

三、主活動界面:

 

 

package com.ydl.music;

import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu;
import android.view.View;

public class MainActivity extends Activity {
	
	MusicInterface mi;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		Intent intent = new Intent(this, MusicService.class);
		//注意:這裡需要混合調用
		/**
		 * 混合調用:既要調用startservice有需要bindService。因為只調用bindService服務與活動綁定在一起的,當用戶返回鍵使得activity進入後台
		 * 此時服務也會進入後台模式,很容易被殺死進程。從而沒法播放音樂。
		 */
		startService(intent);
		bindService(intent, new MusicServiceConn(), BIND_AUTO_CREATE);//第二個參數是一個服務連接對象,活動與服務的關聯起著很重要的作用
	}
	
	class MusicServiceConn implements ServiceConnection{//服務連接方法

		@Override//與服務綁定的時候調用
		public void onServiceConnected(ComponentName name, IBinder service) {
			mi = (MusicInterface) service;
			
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			
		}
		
	}
	
	

	public void start(View v) {
		mi.play();
	}

	public void stop(View v) {
		mi.pause();
	}
}

四、去清單文件配置我們自定義的服務

 

 


運行後可以實現活動調用服務的方法,實現音樂播放器的播放與暫停,同時及時在後台時,服務進程也很難被殺掉。(當然這裡播放音樂的邏輯僅僅是打印一行log)

 

 

好了。有了上邊的基礎,就來開始探討AIDL通信了。

還是給出一張圖。大致看一下意思:

\

場景:兩個項目,01和02.其中01項目是一個服務類,有一些方法;02項目是一個activity類。02項目想去使用01項目服務中的方法,就需要跨進程進行通信。

使用傳統的bindservice()方法已經沒辦法,因此使用AIDL技術——

 

AIDL技術使用步驟:(注意:此時必須隱式方式綁定服務)

 

  • Android interface definition language
  • 進程間通信
  • 把遠程服務的方法抽取成一個單獨的接口java文件
  • 把接口java文件的後綴名改成aidl
  • 在自動生成gen文件中的PublicBusiness.java文件中,有一個靜態抽象類Stub,它已經繼承了Binder類,實現了publicBusiness接口,這個抽象類就是新的中間人
  • 把aidl文件復制粘貼到06項目,粘貼的時候注意,aidl文件所在的包名必須跟05項目中aidl所在的包名一致。此時06項目中也擁有了與05一模一樣的Stub類
  • 在06項目中,強轉中間人對象時,直接使用Stub.asInterface()。它直接做了強制轉 一、定義遠程服務程序:(這裡模擬支付寶支付功能,遠程服務定義名稱為PayService,中間人類定義為小胖子PayPangzhi)

     

    1、把上邊接口的文件修改後綴名為aidl

    改遠程服務端的代碼:

     

    package com.ydl.remoteservice;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.os.RemoteException;
    
    import com.ydl.remoteservice.PayInterface.Stub;
    
    public class PayService extends Service {
    
    	@Override
    	public IBinder onBind(Intent intent) {
    		// TODO Auto-generated method stub
    		return new PayPangZhi();
    	}
    
    	class PayPangZhi extends Stub {//胖紙作為中間人,注意繼承的是Stub類
    
    		@Override
    		public void pay() throws RemoteException {
    			PayService.this.pay();
    			
    		}
    	}
    
    	public void pay() {//虛假的支付功能,以log方式模擬
    		System.out.println("加測運行環境");
    		System.out.println("加密用戶名和密碼");
    		System.out.println("建立連接");
    		System.out.println("完成支付");
    	}
    
    }
    

     

    活動中的方法:

     

    package com.example.startpayservice;
    
    import com.ydl.remoteservice.PayInterface;
    import com.ydl.remoteservice.PayInterface.Stub;
    
    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.view.View;
    
    public class MainActivity extends Activity {
    	
    	PayInterface pi;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            Intent intent = new Intent();//隱式綁定服務
            intent.setAction("com.ydl.pangzhi");
            bindService(intent, new ServiceConnection() {//第二個鏈接對象采用匿名內部類方式
    			
    			@Override
    			public void onServiceDisconnected(ComponentName name) {
    				
    				
    			}
    			
    			@Override
    			public void onServiceConnected(ComponentName name, IBinder service) {
    				pi = Stub.asInterface(service);//這裡自動做了強制類型轉換
    				
    			}
    		}, BIND_AUTO_CREATE);
        }
        
        public void click(View v){
        	try {
    			pi.pay();
    		} catch (RemoteException e) {//請求遠程服務支付異常
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
        }
        
    }
    

    清單文件中配置方式改為隱式:

     

     

    
                
                    
                
            

    終於完成,本篇寫了好久才完成~~~~(>_<)~~~~趕快留下您的而腳印吧!
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved