android面试service,Android面试,与Service交互方式(4)
自定義接口交互
4何謂自定義接口呢,其實就是我們自己通過接口的實現來達到Activity與Service交互的目的,我們通過在Activity和Service之間架設一座橋樑,從而達到數據交互的目的,而這種實現方式和AIDL非常類似(后文會說到)。
4.1 實現原理
自定義一個接口,該接口中有一個獲取當前下載進度的空方法。Server端用一個類繼承自Binder并實現該接口,覆寫了其中獲取當前下載進度的方法。Client端通過ServiceConnection獲取到該類的對象,從而能夠使用該獲取當前下載進度的方法,最終實現實時交互。
4.2 實現步驟
4.2.1 新建一個Interface,并在其中創建一個用于獲取當前下載進度的的空方法getCurrentLoad()
publicinterfaceICountService?{
publicintgetCurrentLoad();
}
4.2.2 新建Server端DownService實現ICountService并在其中通過一個內部類ServiceBinder繼承自Binder并實現ICoutService接口。
publicclassDownLoadServiceextendsServiceimplementsICountService{
privateServiceBinder?serviceBinder?=newServiceBinder();
publicclassServiceBinderextendsBinderimplementsICountService{
@Override
publicintgetCurrentLoad()?{
Log.i(TAG,?"ServiceBinder?getCurrentLoad()...?i=:"+i);
returni;
}
}
@Override
publicintgetCurrentLoad()?{
return0;
}
}
在Server端中,實現獲取下載進度的空方法getCurrentLoad();這是Eclipse自動生成的,重點不在這裡。我們需要在ServiceBinder類中覆寫getCurrentLoad()方法,這裡我們返回當前的下載進度i。
4.2.3 Client端使用bindService()綁定Server端。
if(startSerBtn?==?v)?{
Log.i(TAG,?"Start?Button?Clicked.");
bindService(intent,?serConn,?BIND_AUTO_CREATE);
timer.schedule(newMyTimerTask(),1000,?TIME?*1000);//這里一定要延遲一下再開始獲取數據,不然會報空指針異常
}
在Client端綁定Server端的同時,延遲1s開始獲取下載進度。其中的intent = new Intent(“com.seven.test”);com.seven.test該字符串要與在AndroidManifest.xml中申明的一致
4.2.4 Server端返回binder對象。
@Override
publicIBinder?onBind(Intent?intent)?{
Log.i(TAG,?"DownLoadService.onBind()...");
returnserviceBinder;
}
這里的serviceBinder因為繼承了Binder因此也是Binder對象。
4.2.5 Client端通過ServiceConnection來獲取Server端的binder對象。
privateServiceConnection?serConn?=newServiceConnection()?{
@Override
publicvoidonServiceDisconnected(ComponentName?name)?{
iCountService?=?null;
}
@Override
publicvoidonServiceConnected(ComponentName?name,?IBinder?service)?{
Log.i(TAG,?"onServiceConnected()...");
iCountService?=?(ICountService)service;
}
};
獲取的過程是在bindService()過程中完成的,這里的iCountService是接口ICountService的對象,在這里得到實例化。
4.2.6 在綁定完成之后,Server端會開啟下載,在實際情況中Server端會開啟獨立線程用于下載,這里用i++來代替。
@Override
publicvoidonCreate()?{
super.onCreate();
Log.i(TAG,?"DownLoadService.onCreate()...");
timer?=?newTimer();
timer.schedule(newMyTimerTask(),0,?TIME*1000);
}
classMyTimerTaskextendsTimerTask{
@Override
publicvoidrun()?{
if(100==i){
i=0;
}
i++;
}
}
bindService()方法執行之后會調用DownLoadService中的onCreate()方法,在其onCreate()方法中開啟timer使得i++。
4.2.7 Server端已經開啟了下載,那么Client端需要及時獲取下載進度并在主界面上更新。
Handler?mHandler?=newHandler(){
@Override
publicvoidhandleMessage(Message?msg)?{
super.handleMessage(msg);
Log.i(TAG,?"handleMessage...");
intcurLoad?=?iCountService.getCurrentLoad();
mProgressBar.setProgress(curLoad);
currentTv.setText(curLoad+"%");
}
};
classMyTimerTaskextendsTimerTask{
@Override
publicvoidrun()?{
mHandler.sendMessage(mHandler.obtainMessage());
}
}
Client端的Timer在bindService()完成之后1秒再開始獲取下載進度,獲取方法是直接通過int curLoad = iCountService.getCurrentLoad();這里的getCurrentLoad()方法是DownLoadService內部類ServiceBinder中的方法。Client端將獲取到的下載進度更新到介面上并更新進度條。
4.3 小結
通過上面的例子可以知道,這種方法簡單實用,擴展性強,但其也有一些缺點,比如需要延遲一些再開始獲取Server端的數據,從而無法完全實現從零開始同步更新。綜其所述,通過自定義接口實現Activity與Service交互的方法還是比較實用的。適用於同進程中通信,不能進行跨進程通信。
總結
以上是生活随笔為你收集整理的android面试service,Android面试,与Service交互方式(4)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vscode 头文件包含问题_使用cla
- 下一篇: android sina oauth2.