Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> AIDL/IPC Android AIDL/IPC 進程通信機制——超詳細講解及用法案例剖析(播放器)

AIDL/IPC Android AIDL/IPC 進程通信機制——超詳細講解及用法案例剖析(播放器)

編輯:關於Android編程

首先引申下AIDL,什麼是AIDL呢?IPC? ------ Designing a Remote Interface Using AIDL

通常情況下,我們在同一進程內會使用Binder、BroadCastReciver讓Service跟Activity進行通信,數據交互,數據共享,但是跨進程呢?

IPC:IPC接口,IPC接口本地代理 ------ Implementing IPC Using AIDL

AIDL意為:Android Interface Define Language 即 Android 接口描述語言

與J2ee的區別:Java中不允許跨進程內存共享,只傳遞對象,采用RMI方式,也可以通過序列化傳遞對象

Android AIDL: 采用AIDL方式,可以傳遞Bundle,實現起來稍微麻煩些

實現過程:在服務端定義AIDL文件,ADT插件編譯器將其編譯之後,會在R文件同級目錄文件下生成.java文件,輕量級,使用代理類在客戶端和實現層間傳

遞值

語法:可以申明接口和方法,參數和返回值不是任何類型,不需要申明import,String,charSequence等

AIDL使用起來也不是很麻煩,我個人感覺很實用!所以今天就說說關於AIDL的特性,很多朋友在自己的博客只是說它的理論而不是寫一些實例來講解,我個人感覺你只是說說他的

理論,一般人根本就看不懂,而且本來就是很抽象的東西,又摸不著,你們寫了也是白寫!

完全不顧新手的感受,應該是寫一些小例子,讓大家參與進來一起學習和探討效果才最佳!而且也不是一大堆的文字,看起來也不會那麼乏味,大家說是不?

下面就開始今天的AIDL/IPC講解與學習吧~,概念都講的差不多了,接下來就是實戰,代碼小例子給初學者細嚼慢咽

從服務端線程開始寫,結構圖:

\

EngineerJspRemoteService.aidl 寫完之後保存,就會在gen文件自動創建一個.java文件

\

EngineerJspService.java

package com.example.engineerjspserver;
/**
 * AIDL/IPC 
 * @author Engineer-Jsp
 * @date 2014.11.17
 * */
import java.io.FileDescriptor;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class EngineerJspService extends Service{
	private static final String TAG = "EngineerJspService";
    MediaPlayer player;
	@Override
	public IBinder onBind(Intent intent) {
		Log.d(TAG, "EngineerJspService is onBind..."+"\n來自客戶端的綁定操作已經完成...");
		if(player==null){
			player = MediaPlayer.create(this, R.raw.music);
			player = new MediaPlayer();
			try {
				FileDescriptor file = getResources().openRawResourceFd(R.raw.music).getFileDescriptor();
				player.setDataSource(file);
				player.setLooping(true);
			} catch (Exception e) {
				Log.d(TAG, e.toString());
			}
			Log.d(TAG, "player is created..."+"\n服務端播放器已經實例化,准備就緒...");
		}
		return binder;
	}
	private IBinder binder = new EngineerJspRemoteService.Stub() {
		
		@Override
		public void onStop() throws RemoteException {
			try {
				if(player.isPlaying()){
					Log.d(TAG, "客戶端進程對服務端進程執行了暫停操作...");
					player.stop();
				}
			} catch (Exception e) {
				Log.d(TAG, e.toString());
			}
		}
		
		@Override
		public void onPause() throws RemoteException {
			try {
				if(player.isPlaying()){
					return;
				}
				Log.d(TAG, "客戶端進程對服務端進程執行了開始操作...");
				player.prepare();
				player.start();
			} catch (Exception e) {
				Log.d(TAG, e.toString());
			}
		}
	};
	public boolean onUnbind(Intent intent) {
		if(player!=null){
			player.release();
		}
		Log.d(TAG, "EngineerJspService is onUnBind..."+"\n客戶端已經解綁斷線,服務停止了...");
		return super.onUnbind(intent);
		
	};

}
配置文件:




    

    
              
            
                
                
            
        
         
            
                
            
         
    



當完成上述操作之後,需要在res目錄下導入測試文件,比如我的測試文件一個music.mp3,需要與layout文件同級

\

搞定服務端之後,接下來就是客戶端線程編寫,之後進行進程通信測試

把服務端的aidl文件所在的包全部拷貝到客戶端的src下,把aidl文件除外的全部刪掉

\

EngineerJspActivity.java

<喎?/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPjxwcmUgY2xhc3M9"brush:java;">package com.example.engineerjspclient; /** * AIDL/IPC * @author Engineer-Jsp * @date 2014.11.17 * */ import com.example.engineerjspserver.EngineerJspRemoteService; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; public class EngineerJspActivity extends Activity { private static final String TAG = "EngineerJspActivity"; private static final String ACTION = "com.example.engineerjspserver.EngineerJspService"; private EngineerJspRemoteService EJService; private boolean isBind = false; private Button onPause,onStart; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { isBind = false; EJService = null; Log.d(TAG, "onServiceDisconnected" + "————"+"包名:"+name.getPackageName()+" "+"類名: "+name.getClassName()+"\n當客戶端線程斷線操作,服務將被清空..."); } @Override public void onServiceConnected(ComponentName name, IBinder ibinder) { EJService = EngineerJspRemoteService.Stub.asInterface(ibinder); isBind = true; Log.d(TAG, "onServiceConnected————"+"包名:"+name.getPackageName()+" "+"類名: "+name.getClassName()+" "+"ibinder對象: "+ibinder.toString()+"\n客戶端線程與服務端線程連接中..."); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_engineer_jsp); Log.d(TAG, "客戶端線程Activity創建成功,初始化控件與綁定服務中..."); Bind(); intiView(); } @Override protected void onDestroy() { UnBind(); Log.d(TAG, "客戶端線程被銷毀,活動被解綁停止了..."); super.onDestroy(); } public void Bind(){ Log.d(TAG, "Activity已經創建完成,執行綁定服務端線程活動中..."); Intent intent = new Intent(ACTION); bindService(intent, connection, BIND_AUTO_CREATE); } public void UnBind(){ if(isBind){ Log.d(TAG, "Activity被銷毀了,與服務端線程的通信將被解綁停止..."); unbindService(connection); EJService = null; isBind = false; } } private void intiView(){ onPause = (Button)findViewById(R.id.onPause); onStart = (Button)findViewById(R.id.onStop); onPause.setOnClickListener(listener); onStart.setOnClickListener(listener); Log.d(TAG, "服務端線程的組件初始化完畢..."); } private OnClickListener listener = new OnClickListener(){ @Override public void onClick(View view) { if(view.getId()==R.id.onPause){ try { EJService.onPause(); Log.d(TAG, "客戶端線程對服務端線程執行了播放操作..."); Toast.makeText(EngineerJspActivity.this,"客戶端線程對服務端線程執行了播放操作...", Toast.LENGTH_SHORT).show(); } catch (Exception e) { Log.d(TAG, e.toString()); } }else{ try { EJService.onStop(); Log.d(TAG, "客戶端線程對服務端線程執行了暫停操作..."); Toast.makeText(EngineerJspActivity.this,"客戶端線程對服務端線程執行了暫停操作...", Toast.LENGTH_SHORT).show(); } catch (Exception e) { Log.d(TAG, e.toString()); } } } }; }
activity_engineer_jsp.xml



    
配置文件:




    

    
        
            
                

                
            
        
    



啟動服務端進程與客戶端進程(不在同一個進程內,也就是不在同一個APK程序之內),在DDMS裡進行進程和堆棧查看

\

當服務端進程開啟之後,會等待客戶端進程接入與操作,類似c/s模式,Socket,客戶端進程開啟之後,服務端測試數據如下

\

客戶端測試數據:

\

服務測試:\

客戶端進程對服務端進程執行了播放操作:

\


客戶端進程對服務端進程執行了暫停操作:


\


兩個進程項目圖結構:


AIDL這個小實例內容就這麼多,概念也說得差不多了,你們好好看看,消化消化~

更多精彩盡在本博,歡迎大家一起學習和交流~!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved