Android Service與Activity的互動
阿新 • • 發佈:2018-12-25
Android中有時候需要在Service中改變Activity的UI,或者在Activity中修改Service中的數值。首先必須使用與Activity繫結的Service,有三種方式可以實現。第一,是使用介面回撥的方式在Activty中實現Service中的介面;第二,使用廣播的方式傳遞;第三,則是用觀察者模式,在Activity中實現update方法。
使用介面回撥的方式在Activty中實現Service中的介面
package com.kkrs.serivce; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.support.annotation.Nullable; import android.util.Log; /** * Created by zd on 2018/12/20. */ //繫結的service public class LocalService extends Service { private final static String TAG = "LocalService"; private int count; private boolean quit; private Thread thread; private LocalBinder binder = new LocalBinder(); /** * 回撥 */ private Callback callback; /** * 提供介面回撥方法 * @param callback */ public void setCallback(Callback callback) { this.callback = callback; } /** * 回撥介面 * * @author lenovo * */ public static interface Callback { /** * 得到實時更新的資料 * * @return */ void getNum(int num); } @Override public void onCreate() { super.onCreate(); Log.e(TAG, "Service is invoke Created"); thread = new Thread(new Runnable() { @Override public void run() { // 每間隔一秒count加1 ,直到quit為true。 while (!quit) { try { Thread.sleep(1000); if(callback!=null){ /* * 得到最新資料 */ callback.getNum(count); } } catch (InterruptedException e) { e.printStackTrace(); } count++; } } }); thread.start(); } public class LocalBinder extends Binder { // 宣告一個方法,getService。(提供給客戶端呼叫) LocalService getService() { // 返回當前物件LocalService,這樣我們就可在客戶端端呼叫Service的公共方法了 return LocalService.this; } } /** * 公共方法 * @return */ public int getCount(){ return count; } @Override public void onDestroy() { Log.e(TAG, "Service is onDestroy"); this.quit = true; super.onDestroy(); } @Override public boolean onUnbind(Intent intent) { Log.e(TAG, "Service is onUnbind"); return super.onUnbind(intent); } @Nullable @Override public IBinder onBind(Intent intent) { Log.e(TAG, "Service is onBind"); return binder; } }
private ServiceConnection conn; private LocalService mService; @Override protected void onCreate(Bundle savedInstanceState) { conn = new ServiceConnection() { /** * 與伺服器端互動的介面方法 繫結服務的時候被回撥,在這個方法獲取繫結Service傳遞過來的IBinder物件, * 通過這個IBinder物件,實現宿主和Service的互動。 */ @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.e("MainActivity", "繫結成功呼叫:onServiceConnected"); // 獲取Binder LocalService.LocalBinder binder = (LocalService.LocalBinder) service; mService = binder.getService(); mService.setCallback(new LocalService.Callback(){ @Override public void getNum(int num) { // TODO Auto-generated method stub Log.e("num","====num===="+num); } }); } /** * 當取消繫結的時候被回撥。但正常情況下是不被呼叫的,它的呼叫時機是當Service服務被意外銷燬時, * 例如記憶體的資源不足時這個方法才被自動呼叫。 */ @Override public void onServiceDisconnected(ComponentName name) { mService=null; } }; final Intent intent = new Intent(this, LocalService.class); btnBind.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Log.e("MainActivity", "繫結呼叫:bindService"); bindService(intent, conn, Service.BIND_AUTO_CREATE); } }); btnUnBind.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 解除繫結 Log.e("MainActivity", "解除繫結:bindService"); if(mService!=null) { Log.e("MainActivity", "mService!=null"); mService = null; unbindService(conn); } } }); btnGetDatas.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mService != null) { // 通過繫結服務傳遞的Binder物件,獲取Service暴露出來的資料 Log.e("MainActivity", "從服務端獲取資料:" + mService.getCount()); } else { Log.e("MainActivity", "還沒繫結呢,先繫結,無法從服務端獲取資料"); } } }); }
使用廣播的方式傳遞
package com.kkrs.serivce; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; import static android.content.ContentValues.TAG; /** * Created by zd on 2018/12/25. */ public class ContentService extends Service { private Thread thread; private boolean flag = true; @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub flag = true; return new LocalBinder(); } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); Log.e(TAG, "Service is invoke Created"); thread = new Thread(new Runnable() { @Override public void run() { // 每間隔一秒count加1 ,直到quit為true。 while (flag) { try { Thread.sleep(1000); asyncSendPerson("ContentService"); } catch (InterruptedException e) { e.printStackTrace(); } } } }); thread.start(); } public final class LocalBinder extends Binder { public ContentService getService() { return ContentService.this; } } public void asyncSendPerson(final String name) { // 休息5秒,模擬非同步任務 new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } //可以在子執行緒中直接傳送廣播 sendContentBroadcast(name); } }).start(); } /** * 傳送廣播 * @param name */ protected void sendContentBroadcast(String name) { // TODO Auto-generated method stub Intent intent=new Intent(); intent.setAction("com.example.servicecallback.content"); intent.putExtra("name", name); sendBroadcast(intent); } }
//廣播 private ServiceReConn connRe; private ContentReceiver mReceiver; public class ServiceReConn implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder binder) { // service = ((LocalBinder) binder).getService(); } @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub // service = null; } } public class ContentReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String name = intent.getStringExtra("name"); Person person = new Person(); person.setName(name); Log.e("ContentReceiver",person.toString()); } } /** * 註冊廣播接收者 */ private void doRegisterReceiver() { mReceiver=new ContentReceiver(); IntentFilter filter = new IntentFilter( "com.example.servicecallback.content"); registerReceiver(mReceiver, filter); }
觀察者模式
public class ObserviceService extends Service { //被觀察者 private MyObservable mObservable; private Thread thread; private boolean flag = true; @Override public IBinder onBind(Intent arg0) { flag = true; return new LocalBinder(); } @Override public void onCreate() { super.onCreate(); mObservable = new MyObservable(); thread = new Thread(new Runnable() { @Override public void run() { // 每間隔一秒count加1 ,直到quit為true。 while (true) { try { Thread.sleep(1000); asyncSendPerson("ObserviceService"); } catch (InterruptedException e) { e.printStackTrace(); } } } }); thread.start(); } public final class LocalBinder extends Binder { public ObserviceService getService() { return ObserviceService.this; } } public void asyncSendPerson(final String name) { // 休息5秒,模擬非同步任務 new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } handler.sendMessage(handler.obtainMessage(0, name)); } }).start(); } /** * 新增觀察者 * @param observer */ public void addObserver(Observer observer) { mObservable.addObserver(observer); } private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { String name = (String) msg.obj; Person person = new Person(); person.setName(name); //通知更新 mObservable.notifyChanged(person); } }; public class MyObservable extends Observable { public void notifyChanged(Object object) { this.setChanged(); this.notifyObservers(object); } } @Override public boolean onUnbind(Intent intent) { flag = false; return super.onUnbind(intent); } @Override public void onDestroy() { super.onDestroy(); flag = false; } }
實現Observer
private ServiceConnection conn; private LocalService mService; //觀察這模式 private MyServiceConn connOb; private ObserviceService observiceService; public class MyServiceConn implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder binder) { observiceService = ((ObserviceService.LocalBinder) binder).getService(); //將當前activity新增為觀察者 observiceService.addObserver(MainActivity.this); } @Override public void onServiceDisconnected(ComponentName name) { observiceService = null; } } @Override public void update(Observable observable, Object o) { Log.e("update","觀察這模式在這裡修改UI"); Person person = (Person) o; Log.e("update",person.toString()); }
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
setContentView(R.layout.activity_main);
btnBindOb = (Button)findViewById(R.id.btnBindOb);
btnUnBindOb = (Button)findViewById(R.id.btnUnBindOb);
final Intent obIntent = new Intent(context, ObserviceService.class);
connOb = new MyServiceConn();
btnBindOb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
bindService(obIntent, connOb, Service.BIND_AUTO_CREATE);
}
});
btnUnBindOb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(observiceService!=null) {
Log.e("MainActivity", "observiceService!=null");
observiceService = null;
unbindService(connOb);
}
}
});
}