編輯:關於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("停止播放音樂"); } }
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(); } }
好了。有了上邊的基礎,就來開始探討AIDL通信了。
還是給出一張圖。大致看一下意思:
場景:兩個項目,01和02.其中01項目是一個服務類,有一些方法;02項目是一個activity類。02項目想去使用01項目服務中的方法,就需要跨進程進行通信。
使用傳統的bindservice()方法已經沒辦法,因此使用AIDL技術——
AIDL技術使用步驟:(注意:此時必須隱式方式綁定服務)
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(); } } }
在Android群裡,經常會有人問我,Android Log是怎麼用的,今天我就把從網上以及SDK裡東拼西湊過來,讓大家先一睹為快,希望對大家入門Android Log有
實驗中只需要編寫相應的xml的代碼,java代碼不需要更改,因為我們這裡只是練習android的界面設計。線性布局:線性布局就是將各種控件按照行或者列依次進行排列。其中本
項目地址:https://github.com/wlkdb/GA_network_info點擊打開鏈接1、整個app分為android客戶端、java服務端和數據層,客戶
前面四篇文章分別介紹了音頻開發必備的基礎知識、如何采集一幀音頻、如何播放一幀音頻、如何存儲和解析wav格式的文件,建議有興趣的小伙伴們先讀一讀,本文則重點關注如何對一幀音