編輯:關於android開發
Bound的Service,通過在Application裡調用bindService()方法來啟動。該類型的Service與Application綁定在一起,一旦綁定的所有Application消失了,Android會Detroy掉該Service。也可以主動調用unbindService()方法來解綁Service。
有時候我們想在Activity中獲知Service的狀態,例如一個音樂播放器,Service負責音樂播放,Activity負責顯示當前歌曲名和播放進度。
可以用Broadcast,這個也不失為一個解決方法。
但如果可以獲取Service實例,那麼就可以調用Service中自定義的一些方法來獲取Service狀態了。
首先要明確的是,第一種類型的Service是無能為力的。因為Activity與Service之間並沒有相關聯的接口,即使這個Service是在Activity裡start的,一旦start,兩者不再有關聯。
一、本地Service調用。
如果Activity與Service在同一應用程序中,兩者間的交互就屬於本地Service調用。
可通過bindService實現,具體操作如下:
1、自定義子類MyService,繼承Service類
2、在MyService類中,自定義內部類MyBinder,繼承Binder類
在內部類中,根據需要交互的數據,創建一些方法,以便Activity可通過這些方法得到Service中的一些數據。或者干脆通過一個方法返回Service實例。
public class MyBinder extends Binder { public MyService getServiceInstance() { return MyService.this; } }3、在Service類中,new一個MyBinder私有成員,並在onBind()方法中return一個MyBinder實例。
之所以這樣做,是因為Service一旦綁定,就會回調onBind()方法,並返回一個Binder對象給Activity。具體看下一個步驟。
4、在Activity中覆寫ServiceConnection接口中的onServiceConnected(ComponentName name, IBinder service)方法,
其中的service參數就是MyService類中onBind()方法返回的MyBinder對象,調用MyBinder對象的自定義方法getServiceInstance()可得到Service實例。
下面是一個DEMO: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(intent); //為了拿到中間人對象 bindService(intent, new MusicServiceConn(), BIND_AUTO_CREATE); } class MusicServiceConn implements ServiceConnection{ @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub mi = (MusicInterface) service; } @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub } } //開始播放按鈕 public void play(View v){ mi.play(); } //暫停播放按鈕 public void pause(View v){ mi.pause(); } }
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(); } //必須繼承binder,才能作為中間人對象返回 class MusicController extends Binder implements MusicInterface{ public void play(){ MusicService.this.play(); } public void pause(){ MusicService.this.pause(); } } public void play(){ System.out.println("播放音樂"); } public void pause(){ System.out.println("暫停播放"); } }
public interface MusicInterface { void play(); void pause(); }
二、跨進程Service調用
跨進程Service調用,即在當前應用程序中,調用另一個應用程序中的Service。
因為Android中,每個應用程序都運行於自己的進程中,擁有獨立的Dalvik虛擬機實例,因而稱為跨進程調用(Inter-Process Comunication)。
可通過AIDL服務來實現。
AIDL(Android Interface Definition Language),是Android定義的一種類似Java的語言。主要用於定義跨進程調用時,服務端跟客戶端用於數據交互的接口。
AIDL服務並不支持所有的Java數據類型。它只支持以下的幾種類型:
1、Java的簡單類型(int, char, boolean等)。無需import
2、String和CharSequence。無需import
3、List和Map。無需import(應當注意的是:List和Map的元素類型必須是AIDL支持的)
4、AIDL自動生成的接口。需要import
5、實現android.os.Parcelable接口的類。需要import
建立簡單的AIDL服務的步驟如下:
(一)服務端步驟:
1、在服務端創建AIDL文件IMyAidl.aidl
AIDL與Java代碼很相近,示例代碼如下:(注意:aidl文件後綴名為.aidl)
interface IMyAidl { void print(); }創建完aidl文件後,ADT會自動調用aidl命令生成相應的Java文件。可查看gen文件夾下是否有一個名為IMyAidl.java的文件。如果沒有,說明.aidl文件有誤。
public class MyService extends Service { private AidlBinder mBinder; //Stub類是上一步驟中,aidl命令生成的Java代碼中的一個類 //該類實現了IBinder接口和IMyAidl接口 //可以通過繼承該類,然後在onBind()方法中返回AidlBinder對象 //如此一來,即可通過AidlBinder對象對AIDL文件中定義的方法進行調用 public class AidlBinder extends Stub { @Override public void print() { System.out.println("Hello world!")//實現AIDL文件中的接口函數 } } @Override public void onCreate() { mBinder = new AidlBinder();//啟動服務時即創建Binder對象 } @Override public IBinder onBind(Intent intent) { return mBinder;//返回Binder對象,讓客戶端獲得Binder對象 } }3、配置AndroidManifest.xml文件
<!--{cke_protected}{C}%3C!%2D%2D%20%E8%87%AA%E5%AE%9A%E4%B9%89%E8%AE%BF%E9%97%AEService%E6%89%80%E9%9C%80%E7%9A%84%E6%9D%83%E9%99%90%20%2D%2D%3E--> <permission android:protectlevel="normal" android:name="thomas.permission.AIDL_SERVICE"> <service android:name="com.thomas.aidlserver.MyService" android:exported="true" android:permission="thomas.permission.AIDL_SERVICE"> <!--{cke_protected}{C}%3C!%2D%2D%20IntentFilter%E5%B1%9E%E6%80%A7%E6%98%AF%E5%BF%85%E4%B8%8D%E5%8F%AF%E5%B0%91%E7%9A%84%20%2D%2D%3E--> <!--{cke_protected}{C}%3C!%2D%2D%20%E5%A6%82%E6%AD%A4%E4%B8%80%E6%9D%A5%EF%BC%8C%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%89%8D%E8%83%BD%E9%80%9A%E8%BF%87%E8%AF%A5action%E8%BF%9C%E7%A8%8B%E8%B0%83%E7%94%A8%E6%9C%8D%E5%8A%A1%E7%AB%AF%E7%9A%84Service%20%2D%2D%3E--> <intent-filter> <action android:name="com.thomas.aidlserver.action.AIDL_SERVICE"> </action></intent-filter> </service></permission>(二)客戶端步驟:
private IMyAidl mAidl; mServiceCon = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //將IBinder類型轉化為IMyAidl類型。 mAidl = IMyAidl.Stub.asInterface(service); } @Override public void onServiceDisonnected(ComponentName name){} } //遠程Service綁定,其中Intent的action參數是服務端在 //AndroidManifest.xml文件中標簽下的 指定的字符串 bindService(new Intent("com.thomas.aidlserver.action.AIDL_SERVICE"), mServiceCon, Service.BIND_AUTO_CREATE); mAidl.print();//調用AIDL文件中聲明的方法
<!--{cke_protected}{C}%3C!%2D%2D%20%E8%AF%B7%E6%B1%82%E8%AE%BF%E9%97%AE%E8%BF%9C%E7%A8%8BService%E6%89%80%E9%9C%80%E7%9A%84%E6%9D%83%E9%99%90%EF%BC%8C%E8%AF%A5%E6%9D%83%E9%99%90%E5%AE%9A%E4%B9%89%E4%BA%8E%E6%9C%8D%E5%8A%A1%E7%AB%AF%E7%9A%84AndroidManifest.xml%E6%96%87%E4%BB%B6%E4%B8%AD%20%2D%2D%3E--> <uses-permission android:name="thomas.permission.AIDL_SERVICE"></uses-permission>
Access中使用sql查詢在ACCESS中使用SQL查詢語句檢查SQL語法時非常有用。 操作步驟如下: 【查詢設計】 直接關閉彈出的【顯示表】 找到【SQL視圖】:
Android 6.0 系統棉花糖新的特性和功能 Get you apps ready for Android 6.0 Marshmallow! 新的功能:運行時的權
Mac搭建Android開發環境,mac搭建android Mac上搭建Android開發環境一般有兩種選擇: 1.Android studio 2.ec
多選按鈕(CheckBox),多選按鈕checkbox今天我們介紹的是Checkbox多選框: 1.Activity //復選框,[基礎控件]---狀態切換控件Com