編輯:關於Android編程
許多人不明白service是用來干嘛的,其實Service作為Android四大組件之一,可以理解為一個運行在後台的Activity,它適用於處理一些不干擾用戶的長時間的後台操作,比如你播放器播放音樂之後跳到其它頁面,音樂需要繼續播放,那麼這個時候就可以將音樂的播放一直運行在後台服務中,需要啟動播放的時候就通過Activity去啟動服務,再通過服務去調用播放,需要停止的時候就停止服務。
舉個例子:如果你的應用是一個聊天的應用,需要創建一個Thread每隔一小段時間就去訪問服務器並實時顯示有沒有人發送了消息給你,那這個時候當你跳轉到別的Activity比如個人設置等頁面,而原來持有該Thread的Activity已經finfish,等你回去的時候已經控制不了你剛才在聊天Activity創建的那個子線程了,同樣也就無法正常關閉這些子線程了。那麼這個時候就需要service了,因為service是獨立於Activity的,可以在其中創建子線程,即使Activity關閉了,也能夠操作管理或者關閉這些子線程。而且不Service也不是和Activity一一對應,可以有多個Activity對應一個Service,這些Thread是無法做到的。
Service的使用方法:
原始方式創建服務:
定義一個類為MyService,繼承自Service,並實現其中唯一的抽象方法:onbind(),其用處見下文:
public class MyService extends Service{ @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null; } }
這樣一個最原始的服務類就創建完成,接下來我們要在Activity中去啟動它(通過intent啟動):
Intent intent = new Intent(MainActivity.this,MyService.class); startService(intent);
這個時候我跑一下程序,會發現程序崩潰了。報錯:android:content:ActivityNotFoundException:Unable to find exnlicit activity class。問題就在於Service也是Android四大組件之一,必須要在AndroidMainfest.xml文件中注冊這個服務:
注冊完成之後再運行一遍,便成功啟動服務。
如何停止服務:
Intent intent = new Intent(MainActivity.this,MyService.class); stopService(intent);
綁定方式創建服務:
以上是通過startService方式啟動服務,這種情況下除非主動關閉,不然即使Activity關閉了,服務依舊可以在後台一直運行
還有另外一種能夠通過與Activity綁定的服務,這種情況下一旦Activity關閉了,服務也會相應關閉:
這時候就需要調用我們一開始說的onBind方法,binder在這個時候就相當於連接點:
在我們自定義的MyService類中,添加一個IBinder對象,並創建一個MyBinder內部類,在裡面定義一個方法能夠獲得當前服務,並且重寫onBind以及onUnBind方法:
public class MyService extends Service{ private final IBinder binder = new MyBinder(); public class MyBinder extends Binder { MyService getService() { return MyService.this; } } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub Log.d("MyService", "onBind..."); return binder; } @Override public boolean onUnbind(Intent intent) { // TODO Auto-generated method stub Log.d("MyService", "onUnBind..."); return super.onUnbind(intent); } }
這種方式下啟動服務需要通過調用onBind方法:
Intent intent = new Intent(MainActivity.this,MyService.class); bindService(intent, connection, Context.BIND_AUTO_CREATE);//這裡即綁定並啟動了服務
可以看到有3個參數,第一個即傳入啟動該MyService的intent,第二個傳入的是一個ServiceConnection對象,第三個是調用系統的變量表示自動綁定,其中,connection的創建如下:
final ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName arg0) { // TODO Auto-generated method stub //onServiceDisconnected()方法在正常情況下是不被調用的,它的調用時機是當Service服務被異外銷毀時 ,例如內存的資源不足時 } @Override public void onServiceConnected(ComponentName arg0, IBinder binder) { // TODO Auto-generated method stub MyBinder mybinder = (MyBinder)binder; MyService myservice = mybinder.getService(); //獲得該服務 //在這裡獲取有關服務的各種信息包括狀態等等 } };
停止服務:通過調用onUnbind方法,傳入剛才的connection,就會停止服務
上文我們用兩種方式演示了如何創建一個初始的Service,但會有疑問:如何查看Service到底運行了沒有?
public boolean isServiceWork(Context mContext, String serviceName) { boolean isWork = false; ActivityManager myAM = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); ListmyList = myAM.getRunningServices(40); if (myList.size() <= 0) { return false; } for (int i = 0; i < myList.size(); i++) { String mName = myList.get(i).service.getClassName().toString(); if (mName.equals(serviceName)) { isWork = true; break; } } return isWork; }
調用這個方法,並傳入當前Activity的context,以及服務名:包名+服務的類名(例如:com.example.MyService)
如果結果返回true則表示正在運行,false表示已經關閉。
Service的生命周期:
原始方式的生命周期:
我們可以通過重寫Service中的onCreate、onStartCommand、onDestroy方法並分別打印日志來進行查看:
public class MyService extends Service{ @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); Log.d("MyService", "onCreate..."); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub Log.d("MyService", "onStartCommand..."); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.d("MyService", "onDestroy..."); } }
在布局文件中創建兩個按鈕:
代碼調用:
startservice = (Button)this.findViewById(R.id.startservice); stopservice = (Button)this.findViewById(R.id.stopservice); startservice.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub Intent intent = new Intent(MainActivity.this,MyService.class); startService(intent); } }); stopservice.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub Intent intent = new Intent(MainActivity.this,MyService.class); stopService(intent); } });
運行程序,點擊啟動服務按鈕,查看logcat打印:
再點擊多幾次啟動服務按鈕:
點擊關閉服務按鈕:
可以看出,當我們第一次點擊啟動服務時,調用了服務的onCreate方法,當我們再點擊多次啟動時,只調用服務的onStartCommand方法,點擊關閉的時候,調用了服務的onDestroy方法。所以我們大概了解了服務的生命周期:
1.第一次啟動服務時,調用onCreate
2.第二次啟動服務時,不會再調用onCreate而是調用onStartCommand
3.關閉服務時,調用onDestroy銷毀
流程圖如下:
綁定方式的生命周期:
代碼上文已經講述,這裡不再描述,同理在onBind和onUnBind方法中打印日志,可得到其運行流程如下:
onCreate --> onBind(只一次,不可多次綁定) --> onUnbind --> onDestory
前言在Android開發中,View一直是Android開發人員的一塊心病,一方面想要進階,一方面又害怕進階,可以說Android的View是進階路上的最大絆腳石,因為它
1、list(列表) 列表是常用的UI控件,mui封裝的列表組件比較簡單,只需要在ul節點上添加.mui-table-view類、在li節點上添加.mui-table-
開發者都知道驗證表單裡的數據是令人厭煩而且容易出錯的,日期輸入框的驗證也是如此。我們可以開發出一個外觀看起來與EditText相同Button,點擊該Button後,會顯
網上一般對進度條的示例都是如何顯示,沒有在任務結束如何關閉的文章,參考其他文章經過試驗之後把整套進度條顯示的簡單示例如下: 建立an