需求:后台開啟一個唱歌服務,這個服務里面有個方法切換歌曲
新建一個SingService繼承系統Service
重寫onCreate()和onDestory()方法
填一個自定義的方法changeSing(String songNume)
主界面里,開啟服務,關閉服務,更改歌曲的按鈕
我們調用api開啟服務,這是系統new出來的,我們沒有得到SingService對象,因此沒法調方法
由於系統框架在創建對象的時候會創建與之對應的上下文,我們自己直接new是得不到上下文的
通過bindService()方法,可以間接建立對Service對象的關系
bindService(service,conn,flags),參數:service是Intent對象,conn是ServiceConnection對象中間人不能為空,選項BIND_AUTO_CREATE,如果不存在就創建
ServiceConnection類是個接口,創建一個內部類MyConn實現這個接口
兩個實現方法onServiceConnected()方法和onServiceDisconnected()方法
在綁定服務的時候會調用SingService對象的onBind()方法,在這個方法里面會返回一個IBinder對象
在onServiceConnected()回調方法里成功綁定以后會得到一個IBInder對象
因為IBinder類是一個接口,因此在SingService里面創建一個公共內部類,MyBinder繼承一個實現類Binder,自定義方法callChangeSing(String name),在這個方法里面調用外部類SingServic的changeSing方法。
這樣設計的原因是,有限的暴露一些方法給別的組件調用,為了安全起見,支付寶里面綁定遠程服務,也用到了這個
這只是演示代碼,正常應該是代理人是一個私有的類,把想暴露的方法抽象到一個接口里面,代理人類實現這個接口,代理人類里面還有一些私有方法,這樣當我們返回代理人對象的時候,必須向上轉型一下,因此就可以保護代理人類里面的私有方法
MainActivity.java
package com.tsh.mybindservice; import com.tsh.mybindservice.SingService.MyIBinder; 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.view.Menu; import android.view.MenuItem; import android.view.View; public class MainActivity extends Activity { private SingService.MyIBinder ibinder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } // 聯系代理人的紐帶 private class MyConn implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { System.out.println("代理人對象返回來了"); ibinder = (MyIBinder) service; } @Override public void onServiceDisconnected(ComponentName name) { } } // 綁定服務 public void startSing(View v) { Intent intent = new Intent(this, SingService.class); bindService(intent, new MyConn(), BIND_AUTO_CREATE); } // 切換歌曲 public void changeSing(View v) { ibinder.callChangeSing("月亮之上"); } }
SingService.java
package com.tsh.mybindservice; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.widget.Toast; public class SingService extends Service { //綁定后的回調 @Override public IBinder onBind(Intent intent) { System.out.println("服務被綁定了"); return new MyIBinder(); } //代理人 public class MyIBinder extends Binder{ public void callChangeSing(String song){ //調用外部類的方法 changeSing(song); } } //切換歌曲 public void changeSing(String song){ Toast.makeText(getApplicationContext(), "切換歌曲"+song, 0).show(); } }