編輯:關於Android編程
四大組件都是運行在主線程
Service是在一段不定的時間運行在後台,不和用戶交互應用組件。每個Service必須在manifest中 通過來聲明。可以通過contect.startservice和contect.bindserverice來啟動。
Service和其他的應用組件一樣,運行在進程的主線程中。這就是說如果service需要很多耗時或者阻塞的操作,需要在其子線程中實現。
定義一個新的服務,要用一個類去繼承Service這個類,Service類中有一個抽象方法onBind()。
一般處理定義一個服務去處理一些事情需要重新覆寫三個方法
①onCreate()
②onStartCommand(Intent intent , int flags ,int startId)
③onDestroy()
onCreate()方法會在服務創建的時候調用 onStartCommand()方法會在每次服務啟動的時候調用 onDestroy()方法會在服務銷毀的時候調用
onCreate()和 onStartCommand()方法的區別:
答:oncreate()方法是在服務第一次創建的時候調用,而 onStartCommand()方法則在每次啟動服務的時候都會調用。
注意:每一個服務都需要在AndroidManifest.xml文件中注冊
<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxoMyBpZD0="三啟動服務和停止服務">三、啟動服務和停止服務
定義一個自定義服務類,然後在主函數中通過按鈕點擊事件進行服務的啟動和停止 通過startService()方法啟動服務
通過stopService()方法停止服務
代碼如下:
[圖片]
注意:startService()和stopService()方法都是定義在Context類中的,所以在活動中可以直接調用這兩個方法,完全是由活動來決定服務何時停止的。如果想讓服務自己停止,則只需要在服務類MyService中的任何一個位置調用stopSelf()方法就可以讓這個服務停下來
五種服務的級別:
(1)Foreground process 前台進程 用戶正在交互 可以理解成相 當於 Activity執行onResume方法
(2)Visible process 可視進程 用戶沒有在交互 但用戶還一直能看得見頁面 相當於Activity執行了onPause方法
(3)Service Process 服務進程 通過startService()開啟了一個服務
(4)Background process 後台進程 當前用戶看不見頁面 相當於Activity執行了onStop方法
(5)Empty process 空進程
service的兩種模式(startService()/bindService()不是完全分離的
● 本地服務 Local Service 用於應用程序內部。
它可以啟動並運行,直至有人停止了它或它自己停止。在這種方式下,它以調用Context.startService()啟動,而以調用Context.stopService()結束。它可以調用Service.stopSelf() 或 Service.stopSelfResult()來自己停止。不論調用了多少次startService()方法,你只需要調用一次stopService()來停止服務。
用於實現應用程序自己的一些耗時任務,比如查詢升級信息,並不占用應用程序比如Activity所屬線程,而是單開線程後台執行,這樣用戶體驗比較好。
● 遠程服務 Remote Service 用於android系統內部的應用程序之間。
它可以通過自己定義並暴露出來的接口進行程序操作。客戶端建立一個到服務對象的連接,並通過那個連接來調用服務。連接以調用Context.bindService()方法建立,以調用 Context.unbindService()關閉。多個客戶端可以綁定至同一個服務。如果服務此時還沒有加載,bindService()會先加載它。
服務不能自己運行,需要通過調用Context.startService()或Context.bindService()方法啟動服務。這兩個方法都可以啟動Service,但是它們的使用場合有所不同。 1. 使用startService()方法啟用服務,調用者與服務之間沒有關連,即使調用者退出了,服務仍然運行。 如果打算采用Context.startService()方法啟動服務,在服務未被創建時,系統會先調用服務的onCreate()方法,接著調用onStart()方法。 如果調用startService()方法前服務已經被創建,多次調用startService()方法並不會導致多次創建服務,但會導致多次調用onStart()方法。 采用startService()方法啟動的服務 只能調用Context.stopService()方法結束服務,服務結束時會調用onDestroy()方法。 2. 使用bindService()方法啟用服務,調用者與服務綁定在了一起,調用者一旦退出,服務也就終止,大有“不求同時生,必須同時死”的特點。 onBind()只有采用Context.bindService()方法啟動服務時才會回調該方法。該方法在調用者與服務綁定時被調用,當調用者與服務已經綁定 多次調用Context.bindService()方法並不會導致該方法被多次調用。 采用Context.bindService()方法啟動服務時只能調用onUnbind()方法解除調用者與服務解除,服務結束時會調用onDestroy()方法。
看看官方給出的比較流程示意圖:
擁有service的進程具有較高的優先級
官方文檔告訴我們,Android系統會盡量保持擁有service的進程運行,只要在該service已經被啟動(start)或者客戶端連接(bindService)到它。當內存不足時,需要保持,擁有service的進程具有較高的優先級。
1. 如果service正在調用onCreate,onStartCommand或者onDestory方法,那麼用於當前service的進程則變為前台進程以避免被killed。
2. 如果當前service已經被啟動(start),擁有它的進程則比那些用戶可見的進程優先級低一些,但是比那些不可見的進程更重要,這就意味著service一般不會被killed.
3. 如果客戶端已經連接到service (bindService),那麼擁有Service的進程則擁有最高的優先級,可以認為service是可見的。
4. 如果service可以使用startForeground(int, Notification)方法來將service設置為前台狀態,那麼系統就認為是對用戶可見的,並不會在內存不足時killed。
如果有其他的應用組件作為Service,Activity等運行在相同的進程中,那麼將會增加該進程的重要性。
服務是在後台運行 可以理解成是沒有界面的activity
定義四大組件的方式都是一樣的
定義一個類繼承Service
1.特點:
(1)服務通過startservice方式開啟 第一次點擊按鈕開啟服務 會執行服務的onCreate 和 onStart方法
(2)如果第二次開始再點擊按鈕開啟服務 服務只會執行onStrat方法
(3)服務被開啟後 會在設置頁面裡面的 running裡面找得到這個服務
*(4)startservice 方式開啟服務 服務就會在後台長期運行 直到用戶手工停止 或者調用StopService方法 服務才會被銷毀
自定義的Service服務類裡面的onBind()方法是在activity中執行了bindService()綁定服務的操作後執行的。
bindService()方法中藥傳入三個參數:
第一個參數是Intent對象;
第二個參數是建立連接的對象,即ServiceConnection的對象,當執行了bindService()後,服務和activity之間的聯系便建立起來了,此時會回調Service中的onBind()方法,該方法返回一個IBinder對象,這個對象我們可以在該類中自定義一個MyBinder類繼承Bind抽象類,在裡面實現服務的方法,當onBind()執行後,活動中的ServiceConnection類的onServiceConnection()方法會執行,在該方法裡有傳過來的一個參數IBinder service,將這個參數拿出來,通過這個對象去調用服務中的方法,相當於中間人;
//服務中自定義的中間人對象類 public class MyBinder extends Binder{ public void startDownload(){ xxxxxxxxxx; }; } ...... //連接服務的對象 private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { myBinder = (MyService.MyBinder) service; myBinder.startDownload(); } };
第三個參數是一個標志位,這裡傳入BIND_AUTO_CREATE表示在Activity和Service建立關聯後自動創建Service,這會使得MyService中的onCreate()方法得到執行,但onStartCommand()方法不會執行。
(1)當點擊按鈕第一次開啟服務 會執行服務的onCreate方法 和 onBind()方法
(2) 當第二次點擊按鈕在調用bindservice 服務沒有響應
**(3) 當activity銷毀的時候服務也銷毀 不求同時生但求同時死
(4)通過bind方式開啟服務 服務不能再設置頁面裡面找到 相當於是一個隱形的服務
(1)創建我們要注冊的廣播接收者
public class ScreenReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //獲取廣播事件的類型 String action = intent.getAction(); if ("android.intent.action.SCREEN_OFF".equals(action)) { System.out.println("說明屏幕鎖屏了"); }else if("android.intent.action.SCREEN_ON".equals(action)){ System.out.println("說明屏幕解鎖了"); } } }
public class ScreenService extends Service { private ScreenReceiver receiver; @Override public IBinder onBind(Intent intent) { return null; } //當服務第一次啟動的時候調用 @Override public void onCreate() { //在這個方法裡面注冊廣播接收者 //[1]獲取ScreenReceiver實例 receiver = new ScreenReceiver(); //[2]創建IntentFilter對象 IntentFilter filter = new IntentFilter(); //[3]添加注冊的事件 filter.addAction("android.intent.action.SCREEN_OFF"); filter.addAction("android.intent.action.SCREEN_ON"); //[4]通過代碼的方式注冊 registerReceiver(receiver, filter); super.onCreate(); } //當服務銷毀的時候調用 @Override public void onDestroy() { //當actvivity銷毀的時候 取消注冊廣播接收者 unregisterReceiver(receiver); super.onDestroy(); } }`
(3)一定要記得配置service
5 為什麼要引入bindService
目的為了調用服務裡面的方法
創建前台Service
Service幾乎都是在後台運行的,一直以來它都是默默地做著辛苦的工作。但是Service的系統優先級還是比較低的,當系統出現內存不足情況時,就有可能會回收掉正在後台運行的Service。如果你希望Service可以一直保持運行狀態,而不會由於系統內存不足的原因導致被回收,就可以考慮使用前台Service。前台Service和普通Service最大的區別就在於,它會一直有一個正在運行的圖標在系統的狀態欄顯示,下拉狀態欄後可以看到更加詳細的信息,非常類似於通知的效果。當然有時候你也可能不僅僅是為了防止Service被回收才使用前台Service,有些項目由於特殊的需求會要求必須使用前台Service,比如說墨跡天氣,它的Service在後台更新天氣數據的同時,還會在系統狀態欄一直顯示當前天氣的信息
public class MyService extends Service { public static final String TAG = "MyService"; private MyBinder mBinder = new MyBinder(); @Override public void onCreate() { super.onCreate(); Notification notification = new Notification(R.drawable.ic_launcher, "有通知到來", System.currentTimeMillis()); Intent notificationIntent = new Intent(this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); notification.setLatestEventInfo(this, "Title", "Message", pendingIntent); startForeground(1, notification); Log.d(TAG, "onCreate() executed"); } ......... }
這裡只是修改了MyService中onCreate()方法的代碼。可以看到,首先創建了一個Notification對象,然後調用了它的setLatestEventInfo()方法來為通知初始化布局和數據,並在這裡設置了點擊通知後就打開MainActivity。然後調用startForeground()方法就可以讓MyService變成一個前台Service,並會將通知的圖片顯示出來。
前言很多人要實現輪播圖都會想到使用ViewPager + Handler來完成輪播圖的效果。但是在RxJava快速發展的情況下,已經可以使用RxJava來代替Handle
序最近在學習有關如何porting sensor的東西,僅借此機會寫博客來督促自己進步,當然如果,有人對博客提出不同的理解,我覺得這是極好的,大家可以共同進步。在這一期的
對於SlidingDrawer,官網上是這樣解釋的:SlidingDrawer將內容隱藏在屏幕之外,並且允許用戶通過拖動handle將內容顯示到屏幕上。一個Sliding
前言現在很多應用都會用到地圖,但是我們肯定不想自己的app中還要弄個導航神馬的,所以第三方的地圖也為我們開辟了一條捷徑,直接將數據傳輸到地圖應用,讓第三方的地圖幫我們來做