編輯:關於Android編程
一、AIDL Service簡介
Android系統中,各個應用都運行在自己的進程中,進程之間一般無法直接進行通信,為了實現進程通信(interprocess communication,簡稱IPC),Android提供了AIDL Service;
二、與本地Service不同
本地Service:直接把IBinder對象本身傳遞給客戶端的ServiceConnection的onServiceConnected方法的第二個參數;
遠程Service:只將IBinder對象的代理傳給客戶端的ServiceConnection的onServiceConnected方法的第二個參數;
三、AIDL文件
Android需要AIDL(Android Interface Definition Language)來定義遠程接口,這種接口定義語言並不是一種真正的變成語言,只是定義兩個進程之間的通信接口;
與Java接口相似,但是存在如下幾點差異:
AIDL定義接口的源代碼必須以.aidl結尾;
AIDL用到的數據類型,除了基本類型、String、List、Map、CharSequence之外,其它類型全部都需要導包,即使它們在同一個包中也需要導包;
四、使用AIDL的步驟(詳細代碼可見AIDLService和AIDLClient項目)
1.創建AIDL文件
package com.example.aidlservice; interface ICat { String getColor(); double getWeight(); }定義好AIDL文件後,ADT工具會自動在gen/com/example/aidlservice/目錄下生成一個ICat.java接口,該類內部包含一個Stub內部類,實現了IBinder,ICat兩個接口,這個Stub類會作為遠程Service回調類;
2.將接口暴露給客戶端
package com.example.aidlservice; import java.util.Timer; import java.util.TimerTask; import com.example.aidlservice.ICat.Stub; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; public class AidlService extends Service { String[] colors = new String[] { "紅色", "黃色", "黑色" }; double[] weights = new double[] { 2.3, 3.1, 1.58 }; private String color; private double weight; private CatBinder catBinder; Timer timer = new Timer(); @Override public void onCreate() { super.onCreate(); catBinder = new CatBinder(); timer.schedule(new TimerTask() { @Override public void run() { // 隨機地改變service組件內的color,weight屬性的值 int rand = (int) (Math.random() * 3); color = colors[rand]; weight = weights[rand]; System.out.println("---------" + rand); } }, 0, 800)}; @Override public IBinder onBind(Intent arg0) { /** * 返回CatBinder對象,在綁定本地Service情況下, * 該catBinder會直接傳給客戶端的ServiceConnected對象的ServiceConnected * ()方法的第二個參數;在綁定遠程Service的情況下 * ,只將catBinder對象的代理傳給客戶端的ServiceConnected對象的ServiceConnected()方法的第二個參數 */ return catBinder; } @Override public void onDestroy() { timer.cancel(); } /** * 繼承Stub,也就是實現了ICat接口,並實現了IBinder接口 * * @author pengcx * */ public class CatBinder extends Stub { @Override public String getColor() throws RemoteException { return color; } @Override public double getWeight() throws RemoteException { return weight; } } }
在AndroidManifext.xml文件中配置該Service;
3.客戶端訪問AIDLService
將Service端的AIDL文件復制到客戶端中,注意要在相同的包名下。
package com.example.aidlclient; import com.example.aidlservice.ICat; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.app.Activity; import android.app.Service; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; public class AidlClient extends Activity { private ICat catService; private Button getButton; private EditText colorEditText, weightEditText; private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { catService = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { // 獲取遠程Service的onBinder方法返回的對象代理 catService = ICat.Stub.asInterface(service); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_aidl_client); getButton = (Button) findViewById(R.id.getbutton); colorEditText = (EditText) findViewById(R.id.coloredittext); weightEditText = (EditText) findViewById(R.id.weightedittext); // 創建所需要綁定的Service的Intent Intent intent = new Intent(); intent.setAction("org.crazyit.aidl.action.AIDL_SERVICE"); // 綁定遠程的服務 bindService(intent, conn, Service.BIND_AUTO_CREATE); getButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 獲取並顯示遠程service的狀態 try { colorEditText.setText(catService.getColor()); weightEditText.setText(catService.getWeight() + ""); } catch (RemoteException e) { e.printStackTrace(); } } }); } @Override protected void onDestroy() { super.onDestroy(); // 解除綁定 this.unbindService(conn); } }
錯誤:java.lang.SecurityException: Binder invocation to an incorrect interface。在使用上請注意,服務端與客戶端都要有相同的接口(使用到的),這裡的“相同”是指完全相同,包括包名,也就是說要在不同工程下建立相同的包名。
序言上一篇中我們介紹了幾個簡單的新UI控件,相信很多小伙伴對Materil Design的視覺效果有了一定的了解,今天我們就繼續介紹其他幾個控件的玩兒法,讓我們一探Mat
網上很多關於Android事件分發機制的解釋,大多數描述的都不夠清晰,沒有吧來龍去脈搞清楚,本文將帶你從Touch事件產生到Touch事件被消費這一全過程作
先看下項目結構: http多線程斷點下載涉及到 數據庫,多線程和http請求等幾個模塊,東西不是很多,想弄清楚也不是很困難,接下來我和大家分享下我的做法。 一、先看Ma
本文實例講述了Android編程中的Menu功能菜單。分享給大家供大家參考,具體如下:Android功能菜單的設計,程序裡定義了兩個菜單子項,一個是關於,一個是退出,當點