編輯:關於Android編程
Service 是否在 main thread 中執行, service 裡面是否 能執行耗時的操作?
默認情況,如果沒有顯示的指 servic 所運行的進程, Service 和 activity 是運 行在當前 app 所在進程的 main thread(UI 主線程)裡面。
service 裡面不能執行耗時的操作(網絡請求,拷貝數據庫,大文件 )
特殊情況 ,可以在清單文件配置 service 執行所在的進程 ,讓 service 在另 外的進程中執行
Activity 怎麼和 Service 綁定,怎麼在 Activity 中啟動自 己對應的 Service?
Activity 通過 bindService(Intent service, ServiceConnection conn, int flags)跟 Service 進行綁定,當綁定成功的時候 Service 會將代理對象通過回調 的形式傳給 conn,這樣我們就拿到了 Service 提供的服務代理對象。
在 Activity 中可以通過 startService 和 bindService 方法啟動 Service。一 般情況下如果想獲取 Service 的服務對象那麼肯定需要通過 bindService()方 法,比如音樂播放器,第三方支付等。如果僅僅只是為了開啟一個後台任務那麼 可以使用 startService()方法。
Service 的生命周期
Service 有綁定模式和非綁定模式,以及這兩種模式的混合使用方式。不同 的使用方法生命周期方法也不同。
非綁定模式:當第一次調用 startService 的時候執行的方法依次為 onCreate()、onStartCommand(),當 Service 關閉的時候調用 onDestory 方 法。
綁定模式:第一次 bindService()的時候,執行的方法為 onCreate()、 onBind()解除綁定的時候會執行 onUnbind()、onDestory()。
上面的兩種生命周期是在相對單純的模式下的情形。我們在開發的過程中還 必須注意 Service 實例只會有一個,也就是說如果當前要啟動的 Service 已經存 在了那麼就不會再次創建該 Service 當然也不會調用 onCreate()方法。
一個 Service 可以被多個客戶進行綁定,只有所有的綁定對象都執行了
onBind()方法後該 Service 才會銷毀,不過如果有一個客戶執行了 onStart() 方法,那麼這個時候如果所有的 bind 客戶都執行了 unBind()該 Service 也不會 銷毀。
Service 的生命周期圖如下所示,幫助大家記憶。
什麼是 IntentService?有何優點?<喎?/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPjwvcD4NCjxwPs7Sw8fNqLOj1ru74cq508MgU2VydmljZSy/ycTcIEludGVudFNlcnZpY2UgttS087K/t9bNrNGnwLTLtba8yse12iDSu7TOzP3LtaGjxMfDtL+0wcvPwsPmtcS96cncz+DQxcTjvs2yu9TZxLDJ+sHLoaPI57n7xOO7ucrHsrvBy73ixMfDtNTaIMPmytS1xMqxuvLE477NzLmzz8u1w7vTw7n9u/LV37K7wcu94rXIoaOyorK7ysfL+dPQtcTOyszitrzQ6NKqu9i08MnPwLS1xKGjPGJyIC8+DQrSu6GiPHN0cm9uZz5JbnRlbnRTZXJ2aWNlPC9zdHJvbmc+ILzyvek8YnIgLz4NCkludGVudFNlcnZpY2UgyscgU2VydmljZSC1xNfTwOAsscjG1c2otcQgU2VydmljZSDU9rzTwcu27s3itcS5psTcoaM8YnIgLz4NCs/Iv7QgU2VydmljZSCxvsnttObU2sG9uPbOysziOjxiciAvPg0KU2VydmljZSCyu7vh16jDxcb0tq/Su8z1taW2wLXEvfizzCxTZXJ2aWNlINPry/zL+dTa06bTw86709rNrNK7uPa9+DxiciAvPg0Ks8zW0Ds8YnIgLz4NClNlcnZpY2Ug0rKyu8rH16jDxdK7zPXQws/fs8ws0vK0y7K706a4w9TaIFNlcnZpY2Ug1tDWsb3TtKbA7brEyrG1xDxiciAvPg0KyM7O8Ts8YnIgLz4NCrb+oaI8c3Ryb25nPkludGVudFNlcnZpY2U8L3N0cm9uZz4gzNjV9zxiciAvPg0Ku+G0tL2otsDBorXEIHdvcmtlciDP37PMwLS0psDty/nT0LXEIEludGVudCDH68fzOzxiciAvPg0Ku+G0tL2otsDBorXEIHdvcmtlciDP37PMwLS0psDtIG9uSGFuZGxlSW50ZW50KCm3vbeoyrXP1rXEtPrC6yzO3tDoPGJyIC8+DQq0psDttuDP37PMzsrM4js8YnIgLz4NCsv509DH68fztKbA7c3qs8m68yxJbnRlbnRTZXJ2aWNlILvh19S2r82j1rkszt7Q6LX308Mgc3RvcFNlbGYoKbe9t6g8YnIgLz4NCs2j1rkgU2VydmljZTs8YnIgLz4NCs6qIFNlcnZpY2UgtcQgb25CaW5kKCnM4bmpxKzIz8q1z9Yst7W72CBudWxsOzxiciAvPg0KzqogU2VydmljZSC1xCBvblN0YXJ0Q29tbWFuZCDM4bmpxKzIz8q1z9YsvavH68fzIEludGVudCDM7bzTtb2208HQPGJyIC8+DQrW0Ds8YnIgLz4NCsq508MgSW50ZW50U2VydmljZTxiciAvPg0Ksb7Iy9C0wcvSu7j2IEludGVudFNlcnZpY2UgtcTKudPDwP3X07mpss6/vKGjuMPA/dfT1tDSu7j2PGJyIC8+DQpNYWluQWN0aXZpdHkg0ru49iBNeUludGVudFNlcnZpY2Us1eLBvbj2wOC2vMrHy8S089fpvP61sci70OjSqtTax+W1pSDOxLz+1tDXorLhoaPV4sDv1ru4+LP2usvQxLT6wus6PC9wPg0KPHByZSBjbGFzcz0="brush:java;">
Activity、Intent、Service 是什麼關系 他們都是 Android 開發中使用頻率最高的類。其中 Activity 和 Service 都是 Android 四大組件之一。他倆都是 Context 類的子類 ContextWrapper 的子類, 因此他倆可以算是兄弟關系吧。不過兄弟倆各有各自的本領,Activity 負責用戶 界面的顯示和交互,Service 負責後台任務的處理。Activity 和 Service 之間可 以通過 Intent 傳遞數據,因此可以把 Intent 看作是通信使者。 Service 和 Activity 在同一個線程嗎? Service 裡面可以彈吐司麼 什麼是 Service 以及描述下它的生命周期。Service 有哪 些啟動方法,有什麼區別,怎樣停用 Service? 在 service 的生命周期方法 onstartConmand()可不可以執行網絡操作?如何在 service 中執行網絡操作? 如何提高service的優先級? service 如何定時執行? Service 的 onStartCommand 方法有幾種返回值?各代表什麼意思? Service 的 onRebind(Intent)方法在什麼情況下會執行? Activity 調用 Service 中的方法都有哪些方式? Messenger: 這裡畫了一個粗淺的圖幫助大家理解。 Service 如何給 Activity 發送 Message? 關於Service相關基礎知識點,本章節就先總結到這來。希望對大家有所幫助。MainActivity.java:
public void click(View view){
Intent intent = new Intent(this, MyIntentService.class); intent.putExtra("start", "MyIntentService"); startService(intent);
}
MyIntentService.java
public class MyIntentService extends IntentService { private String ex = "";
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) { Toast.makeText(MyIntentService.this, "-e " + ex,
Toast.LENGTH_LONG).show(); }
};
public MyIntentService(){ super("MyIntentService");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) { ex = intent.getStringExtra("start");
return super.onStartCommand(intent, flags, startId);
}
@Override
protected void onHandleIntent(Intent intent) { /**
* 模擬執行耗時任務
* 該方法是在子線程中執行的,因此需要用到 handler 跟主線程進行通信 */
try { Thread.sleep(1000);
} catch (InterruptedException e) { e.printStackTrace();
} mHandler.sendEmptyMessage(0); try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
對於同一 app 來說默認情況下是在同一個線程中的,main Thread (UI Thread)。
可以的。彈吐司有個條件就是得有一個 Context 上下文,而 Service 本身就是 Context 的子類,因此在 Service 裡面彈吐司是完全可以的。比如我們在 Service 中完成下載任務後可以彈一個吐司通知用戶。
在 Service 的生命周期中,被回調的方法比 Activity 少一些,只有 onCreate, onStart, onDestroy,
onBind 和 onUnbind。
通常有兩種方式啟動一個 Service,他們對 Service 生命周期的影響是不一樣的。
Service 會經歷 onCreate 到 onStart,然後處於運行狀態,stopService
的時候調用 onDestroy 方法。
如果是調用者自己直接退出而沒有調用 stopService 的話,Service 會一直
在後台運行。 通過 bindService
Service 會運行 onCreate,然後是調用 onBind,這個時候調用者和 Service 綁定在一起。調用者退出了,Srevice 就會調用 onUnbind->onDestroyed 方 法。
所謂綁定在一起就共存亡了。調用者也可以通過調用 unbindService 方法來 停止服務,這時候 Srevice 就會調用 onUnbind->onDestroyed 方法。 需要注意的是如果這幾個方法交織在一起的話,會出現什麼情況呢? 一個原則是 Service 的 onCreate 的方法只會被調用一次,就是你無論多少次的 startService 又 bindService,Service 只被創建一次。
如果先是 bind 了,那麼 start 的時候就直接運行 Service 的 onStart 方法,如 果先是 start,那麼 bind 的時候就直接運行 onBind 方法。
如果 service 運行期間調用了 bindService,這時候再調用 stopService 的話,service 是不會調用 onDestroy 方法的,service 就 stop 不掉了,只能調用 UnbindService, service 就會被銷毀
如果一個 service 通過 startService 被 start 之後,多次調用 startService 的 話,service 會多次調用 onStart 方法。多次調用 stopService 的話,service 只會調用一次 onDestroyed 方法。
如果一個 service 通過 bindService 被 start 之後,多次調用 bindService 的話, service 只會調用一次 onBind 方法。
多次調用 unbindService 的話會拋出異常。
可以直接在 Service 中執行網絡操作,在 onStartCommand()方法中可以執行網絡操作
Android 系統對於內存管理有自己的一套方法,為了保障系統有序穩定的運信,
系統內部會自動分配,控制程序的內存使用。當系統覺得當前的資源非常有限的時候,
為了保 證一些優先級高的程序能運行,就會殺掉一些他認為不重要的程序或者服務來釋放內存。
這樣就能保證真正對用戶有用的程序仍然再運行。如果你的 Service 碰上了這種情況,多半會先被殺掉。
但如果你增加 Service 的優先級就能讓他多留一會,
我們可以用 setForeground(true) 來設置 Service 的優先級。
為什麼是 foreground ? 默認啟動的 Service 是被標記為 background,當前運行的 Activity
一般被標記為 foreground,也就是說你給 Service 設置了 foreground 那麼他就和正在運行的
Activity 類似優先級得到了一定的提高。當讓這並不能保證你得 Service
永遠不被殺掉,只是提高了他的優先級。
當啟動service進行後台任務的時候,我們一般的 做法是啟動一個線程,然後通過sleep方法來控制進行定時的任務,如輪詢操作,消息推送。這樣容易被系統回收。
service被回收是我們不能控制的,但是我們可以控制service的重啟活動。在service的onStartCommand
方法中可以返回一個參數來控制重啟活動
使用AlarmManager,根據AlarmManager的工作原理,alarmmanager會定時的發出一條廣播,然後在自己的項目裡面注冊這個廣播,重寫onReceive方法,在這個方法裡面啟動一個service,然後在service裡面進行網絡的訪問操作,當獲取到新消息的時候進行推送,同時再設置一個alarmmanager進行下一次的輪詢,當本次輪詢結束的時候可以stopself結束改service。這樣即使這一次的輪詢失敗了,也不會影響到下一次的輪詢。這樣就能保證推送任務不會中斷
有四種返回值,不同值代表的意思如下:
START_STICKY:如果 service 進程被 kill 掉,保留 service 的狀態為開始狀態,但不保留遞送的 intent 對象。隨 後系統會嘗試重新創建 service,由於服務狀態為開始狀態,所以創建服務後一定會調用 onStartCommand(Intent,int,int)方法。如果在此期間沒有任何啟動命令被傳遞到 service,那麼參數 Intent 將為 null。
START_NOT_STICKY:“非粘性的”。使用這個返回值時,如果在執行完 onStartCommand 後,服務被異常 kill 掉,系統不會自動重啟該服務。
START_REDELIVER_INTENT:重傳 Intent。使用這個返回值時,如果在執行完 onStartCommand 後,服務被異 常 kill 掉,系統會自動重啟該服務,並將 Intent 的值傳入。
**START_STICKY_COMPATIBILITY:**START_STICKY 的兼容版本,但不保證服務被 kill 後一定能重啟。
如果在 onUnbind()方法返回 true 的情況下會執行,否則不執行。
Binder:
通過 Binder 接口的形式實現,當 Activity 綁定 Service 成功的時候 Activity 會在 ServiceConnection 的類 的 onServiceConnected()回調方法中獲取到 Service 的 onBind()方法 return 過來的 Binder 的子類,然後通過對象調用方法。
Aidl:
aidl 比較適合當客戶端和服務端不在同一個應用下的場景。
它引用了一個Handler對象,以便others能夠向它發送消息(使用mMessenger.send(Message msg)方法)。該類允許跨進程間基於Message的通信(即兩個進程間可以通過Message進行通信),在服務端使用Handler創建一個Messenger,客戶端持有這個Messenger就可以與服務端通信了。一個Messeger不能同時雙向發送,兩個就就能雙向發送了
**BroadCastReceiver**
Service 和 Activity 如果想互發 Message 就必須使用使用 Messenger 機制。IntentService 適用場景
IntentService 內置的是 HandlerThread 作為異步線程,每一個交給 IntentService 的任務都將以隊列的方式逐個被執行到,一旦隊列中有某個任務執行時間過長,那麼就會導致後續的任務都會被延遲處理 正在運行的 IntentService 的程序相比起純粹的後台程序更不容易被系統殺死,該程序的優先級是介於前台程序與純後台程序之間的
前言或許你知道了jni的簡單調用,其實不算什麼百度谷歌一大把,雖然這些jni絕大多數情況下都不會讓我們安卓工程師來弄,畢竟還是有點難,但是我們還是得打破砂鍋知道為什麼這樣
概述:先聲明:本人工作快兩年了,仍是菜鳥級別的,慚愧啊!以前遇到好多知識點都沒有記錄下來,感覺挺可惜的,現在有機會接觸Android 源碼。我們一個Android組的搞S
一、技術概覽1. Core Data 功能初窺對於處理諸如對象生命周期管理、對象圖管理等日常任務,Core Data框架提供了廣泛且自動化的解決方案。它有以下特性。(注:
1. 什麼是dumpsysThe dumpsys tool runs on the device and provides information about the s