Service一般老是稱之爲「後臺服務」,其中「後臺」一詞是相對於前臺而言的,具體是指其自己的運行並不依賴於用戶可視的UI界面,所以,從實際業務需求上來理解,Service的適用場景應該具有如下條件:android
1.並不依賴於用戶可視的UI界面(固然,這一條其實也不是絕對的,如前臺Service就是與Notification界面結合使用的);微信
2.具備較長時間的運行特性。多線程
1.Service AndroidManifest.xml 聲明併發
通常而言,從Service的啓動方式上,能夠將Service分爲Started Service和Bound Service。不管哪一種具體的Service啓動類型,都是經過繼承Service基類自定義而來。在使用Service時,要想系統可以找到此自定義Service,不管哪一種類型,都須要在AndroidManifest.xml中聲明,語法格式以下:ide
1 <service android:enabled=["true" | "false"] 2 android:exported=["true" | "false"] 3 android:icon="drawable resource"
4 android:isolatedProcess=["true" | "false"] 5 android:label="string resource"
6 android:name="string"
7 android:permission="string"
8 android:process="string" >
9 . . . 10 </service>
其中,android:exported屬性上一篇博文中對此已進行詳盡描述,android:name對應Service類名,android:permission是權限聲明,android:process設置具體的進程名稱。須要注意的是Service可否單獨使用一個進程與其啓動方式有關,本後下面會給出具體說明。其餘的屬性此處與其餘組件基本相同,再也不過多描述。函數
注:若是自定義Service沒有在AndroidManifest.xml中聲明,當具體使用時,不會像Activity那樣直接崩潰報錯,對於顯式Intent啓動的Service,此時也會給出waring信息「IllegalArgumentException: Service not registered」,有時候不容易發現忘了聲明而一時定位不到問題。post
2.Started Servicethis
Started Service相對比較簡單,經過context.startService(Intent serviceIntent)啓動Service,context.stopService(Intent serviceIntent)中止此Service。固然,在Service內部,也能夠經過stopSelf(...)方式中止其自己。spa
1)Started Service自定義線程
下面代碼片斷顯示的是一個最基本的Started Service的自定義方式:
1 public class MyService extends Service { 2
3 public static final String TAG = "MyService"; 4
5 @Override 6 public IBinder onBind(Intent intent) { 7 return null; 8 } 9
10 @Override 11 public void onCreate() { 12 super.onCreate(); 13 Log.w(TAG, "in onCreate"); 14 } 15
16 @Override 17 public int onStartCommand(Intent intent, int flags, int startId) { 18 Log.w(TAG, "in onStartCommand"); 19 Log.w(TAG, "MyService:" + this); 20 String name = intent.getStringExtra("name"); 21 Log.w(TAG, "name:" + name); 22 return START_STICKY; 23 } 24
25 @Override 26 public void onDestroy() { 27 super.onDestroy(); 28 Log.w(TAG, "in onDestroy"); 29 } 30 }
其中,onBind(...)函數是Service基類中的惟一抽象方法,子類都必須重寫實現,此函數的返回值是針對Bound Service類型的Service纔有用的,在Started Service類型中,此函數直接返回 null 便可。onCreate(...)、onStartCommand(...)和onDestroy()都是Started Service相應生命週期階段的回調函數。
2) Started Service使用
1 public class MainActivity extends Activity { 2
3 public static final String TAG = "MainActivity"; 4
5 private Button startServiceBtn; 6 private Button stopServideBtn; 7 private Button goBtn; 8
9 private Intent serviceIntent; 10
11 @Override 12 protected void onCreate(Bundle savedInstanceState) { 13 super.onCreate(savedInstanceState); 14 setContentView(R.layout.activity_main); 15
16 startServiceBtn = (Button) findViewById(R.id.start_service); 17 stopServideBtn = (Button) findViewById(R.id.stop_service); 18 goBtn = (Button) findViewById(R.id.go); 19
20 startServiceBtn.setOnClickListener(new View.OnClickListener() { 21 @Override 22 public void onClick(View v) { 23 serviceIntent = new Intent(MainActivity.this, MyService.class); 24 startService(serviceIntent); 25 } 26 }); 27
28 stopServideBtn.setOnClickListener(new View.OnClickListener() { 29 @Override 30 public void onClick(View v) { 31 stopService(serviceIntent); 32 } 33 }); 34
35 goBtn.setOnClickListener(new View.OnClickListener() { 36 @Override 37 public void onClick(View v) { 38 Intent intent = new Intent(MainActivity.this, BActivity.class); 39 startActivity(intent); 40 } 41 }); 42
43 } 44
45 @Override 46 protected void onDestroy() { 47 super.onDestroy(); 48 Log.w(TAG, "in onDestroy"); 49 } 50 }
如上代碼片斷,
當Client調用startService(Intent serviceIntent)後,若是MyService是第一次啓動,首先會執行 onCreate()回調,而後再執行onStartCommand(Intent intent, int flags, int startId),當Client再次調用startService(Intent serviceIntent),將只執行onStartCommand(Intent intent, int flags, int startId),由於此時Service已經建立了,無需執行onCreate()回調。不管多少次的startService,只須要一次stopService()便可將此Service終止,執行onDestroy()函數(其實很好理解,由於onDestroy()與onCreate()回調是相對的)。
下面重點關注下onStartCommand(Intent intent, int flags, int startId)方法。
其中參數flags默認狀況下是0,對應的常量名爲START_STICKY_COMPATIBILITY。startId是一個惟一的整型,用於表示這次Client執行startService(...)的請求請求標識,在屢次startService(...)的狀況下,呈現0,1,2....遞增。另外,此函數具備一個int型的返回值,具體的可選值及含義以下:
START_NOT_STICKY:當Service由於內存不足而被系統kill後,接下來將來的某個時間內,即便系統內存足夠可用,系統也不會嘗試從新建立此Service。除非程序中Client明確再次調用startService(...)啓動此Service。
START_STICKY:當Service由於內存不足而被系統kill後,接下來將來的某個時間內,當系統內存足夠可用的狀況下,系統將會嘗試從新建立此Service,一旦建立成功後將回調onStartCommand(...)方法,但其中的Intent將是null,pendingintent除外。
START_REDELIVER_INTENT:與START_STICKY惟一不一樣的是,回調onStartCommand(...)方法時,其中的Intent將是非空,將是最後一次調用startService(...)中的intent。
START_STICKY_COMPATIBILITY:compatibility version of {@link #START_STICKY} that does not guarantee that {@link #onStartCommand} will be called again after being killed。此值通常不會使用,因此注意前面三種情形就好。
以上的描述中,」當Service由於內存不足而被系統kill後「必定要很是注意,由於此函數的返回值設定只是針對此種狀況纔有意義的,換言之,當認爲的kill掉Service進程,此函數返回值不管怎麼設定,接下來將來的某個時間內,即便系統內存足夠可用,Service也不會重啓。
小米手機針對此處作了變動:
另外,須要注意的是,小米手機針對此處作了必定的修改。在「自啓動管理」中有一個自啓動應用列表,默認狀況下,只有少應用(如微信、QQ、YY、360等)默認是能夠自啓動的,其餘應用默認都是禁止的。用戶能夠手動添加自啓動應用,添加後的應用中若是Started Service onStartCommand(...)回調返回值是START_STICKY或START_REDELIVER_INTENT,當用戶在小米手機上長按Home鍵結束App後,接下來將來的某個時間內,當系統內存足夠可用時,Service依然能夠按照上述規定重啓。固然,若是用戶在 設置 >> 應用 >> 強制kill掉App進程,此時Service是不會重啓的。
注:以上實驗結論基於小米2S親測。
3) Started Service生命週期及進程相關
1.onCreate(Client首次startService(..)) >> onStartCommand >> onStartCommand - optional ... >> onDestroy(Client調用stopService(..))
注:onStartCommand(..)能夠屢次被調用,onDestroy()與onCreate()想匹配,當用戶強制kill掉進程時,onDestroy()是不會執行的。
2.對於同一類型的Service,Service實例一次永遠只存在一個,而無論Client是不是相同的組件,也無論Client是否處於相同的進程中。
3.Service經過startService(..)啓動Service後,此時Service的生命週期與Client自己的什麼週期是沒有任何關係的,只有Client調用stopService(..)或Service自己調用stopSelf(..)才能中止此Service。固然,當用戶強制kill掉Service進程或系統因內存不足也可能kill掉此Service。
4.Client A 經過startService(..)啓動Service後,能夠在其餘Client(如Client B、Client C)經過調用stopService(..)結束此Service。
5.Client調用stopService(..)時,若是當前Service沒有啓動,也不會出現任何報錯或問題,也就是說,stopService(..)無需作當前Service是否有效的判斷。
6.startService(Intent serviceIntent),其中的intent既能夠是顯式Intent,也能夠是隱式Intent,當Client與Service同處於一個App時,通常推薦使用顯示Intent。當處於不一樣App時,只能使用隱式Intent。
當Service須要運行在單獨的進程中,AndroidManifest.xml聲明時須要經過android:process指明此進程名稱,當此Service須要對其餘App開放時,android:exported屬性值須要設置爲true(固然,在有intent-filter時默認值就是true)。
1 <service 2 android:name=".MyService"
3 android:exported="true"
4 android:process=":MyCorn" >
5 <intent-filter>
6 <action android:name="com.example.androidtest.myservice" />
7 </intent-filter>
8 </service>
4)Started Service Client與Service通訊相關
當Client調用startService(Intent serviceIntent)啓動Service時,Client能夠將參數經過Intent直接傳遞給Service。Service執行過程當中,若是須要將參數傳遞給Client,通常能夠經過藉助於發送廣播的方式(此時,Client須要註冊此廣播)。
3.Bound Service
相對於Started Service,Bound Service具備更多的知識點。Bound Service的主要特性在於Service的生命週期是依附於Client的生命週期的,當Client不存在時,Bound Service將執行onDestroy,同時經過Service中的Binder對象能夠較爲方便進行Client-Service通訊。Bound Service通常使用過程以下:
1.自定義Service繼承基類Service,並重寫onBind(Intent intent)方法,此方法中須要返回具體的Binder對象;
2.Client經過實現ServiceConnection接口來自定義ServiceConnection,並經過bindService (Intent service, ServiceConnection sc, int flags)方法將Service綁定到此Client上;
3.自定義的ServiceConnection中實現onServiceConnected(ComponentName name, IBinder binder)方法,獲取Service端Binder實例;
4.經過獲取的Binder實例進行Service端其餘公共方法的調用,以完成Client-Service通訊;
5.當Client在恰當的生命週期(如onDestroy等)時,此時須要解綁以前已經綁定的Service,經過調用函數unbindService(ServiceConnection sc)。
在Bound Service具體使用過程當中,根據onBind(Intent intent)方法放回的Binder對象的定義方式不一樣,又能夠將其分爲如下三種方式,且每種方式具備不一樣的特色和適用場景:
1).Extending the Binder class
這是Bound Service中最多見的一種使用方式,也是Bound Service中最簡單的一種。
侷限:Clinet與Service必須同屬於同一個進程,不能實現進程間通訊(IPC)。不然則會出現相似於「android.os.BinderProxy cannot be cast to xxx」錯誤。
下面經過代碼片斷看下具體的使用:
1 public class MyBindService extends Service { 2
3 public static final String TAG = "MyBindService"; 4
5 private MyBinder mBinder = new MyBinder(); 6
7 public class MyBinder extends Binder { 8 MyBindService getService() { 9 return MyBindService.this; 10 } 11 } 12
13 @Override 14 public void onCreate() { 15 super.onCreate(); 16 Log.w(TAG, "in onCreate"); 17 } 18
19 @Override 20 public IBinder onBind(Intent intent) { 21 Log.w(TAG, "in onBind"); 22 return mBinder; 23 } 24
25 @Override 26 public boolean onUnbind(Intent intent) { 27 Log.w(TAG, "in onUnbind"); 28 return super.onUnbind(intent); 29 } 30
31 @Override 32 public void onDestroy() { 33 super.onDestroy(); 34 Log.w(TAG, "in onDestroy"); 35 } 36 }
1 public class BActivity extends Activity { 2
3 public static final String TAG = "BActivity"; 4
5 private Button bindServiceBtn; 6 private Button unbindServiceBtn; 7
8 private Button startIntentService; 9
10 private Intent serviceIntent; 11
12 private ServiceConnection sc = new MyServiceConnection(); 13 private MyBinder mBinder; 14 private MyBindService mBindService; 15 private boolean mBound; 16
17 private class MyServiceConnection implements ServiceConnection { 18
19 @Override 20 public void onServiceConnected(ComponentName name, IBinder binder) { 21 Log.w(TAG, "in MyServiceConnection onServiceConnected"); 22 mBinder = (MyBinder) binder; 23 mBindService = mBinder.getService(); 24
25 mBound = true; 26 } 27
28 @Override 29 public void onServiceDisconnected(ComponentName name) { 30 // This is called when the connection with the service has been 31 // unexpectedly disconnected -- that is, its process crashed.
32 Log.w(TAG, "in MyServiceConnection onServiceDisconnected"); 33 mBound = false; 34 } 35
36 } 37
38 @Override 39 protected void onCreate(Bundle savedInstanceState) { 40 super.onCreate(savedInstanceState); 41 setContentView(R.layout.b); 42
43 bindServiceBtn = (Button) findViewById(R.id.bind_service); 44 unbindServiceBtn = (Button) findViewById(R.id.unbind_service); 45 startIntentService = (Button) findViewById(R.id.start_intentservice); 46
47 bindServiceBtn.setOnClickListener(new View.OnClickListener() { 48 @Override 49 public void onClick(View v) { 50 Intent intent = new Intent(BActivity.this, MyBindService.class); 51 bindService(intent, sc, Context.BIND_AUTO_CREATE); 52 } 53 }); 54
55 unbindServiceBtn.setOnClickListener(new View.OnClickListener() { 56 @Override 57 public void onClick(View v) { 58 excuteUnbindService(); 59 } 60 }); 61
62 startIntentService.setOnClickListener(new View.OnClickListener() { 63 @Override 64 public void onClick(View v) { 65 Intent intent = new Intent(BActivity.this, MyIntentService.class); 66 startService(intent); 67 } 68 }); 69
70 } 71
72 private void excuteUnbindService() { 73 if (mBound) { 74 unbindService(sc); 75 mBound = false; 76 } 77 } 78
79 @Override 80 protected void onDestroy() { 81 super.onDestroy(); 82 Log.w(TAG, "in onDestroy"); 83 excuteUnbindService(); 84 } 85 }
首次點擊bindServiceBtn進行bindService(..)時,依次回調順序以下:
1 MyBindService(13457): in onCreate 2 MyBindService(13457): in onBind 3 BActivity(13457): in MyServiceConnection onServiceConnected
再次點擊bindServiceBtn按鈕時,發現沒有任何輸出,說明MyBindService沒有進行任何回調。
點擊unbindServiceBtn進行unbindService(..)時,回調順序爲:
1 MyBindService(13457): in onUnbind 2 MyBindService(13457): in onDestroy
注:在四大基本組件中,須要注意的的是BroadcastReceiver不能做爲Bound Service的Client,由於BroadcastReceiver的生命週期很短,當執行完onReceive(..)回調時,BroadcastReceiver生命週期完結。而Bound Service又與Client自己的生命週期相關,所以,Android中不容許BroadcastReceiver去bindService(..),當有此類需求時,能夠考慮經過startService(..)替代。
2)Using a Messenger
Messenger,在此能夠理解成」信使「,經過Messenger方式返回Binder對象能夠不用考慮Clinet - Service是否屬於同一個進程的問題,而且,能夠實現Client - Service之間的雙向通訊。極大方便了此類業務需求的實現。
侷限:不支持嚴格意義上的多線程併發處理,其實是以隊列去處理
下面直接看下具體的使用:
1 public class MyMessengerService extends Service { 2
3 public static final String TAG = "MyMessengerService"; 4
5 public static final int MSG_FROM_CLIENT_TO_SERVER = 1; 6 public static final int MSG_FROM_SERVER_TO_CLIENT = 2; 7
8 private Messenger mClientMessenger; 9 private Messenger mServerMessenger = new Messenger(new ServerHandler()); 10
11 @Override 12 public IBinder onBind(Intent intent) { 13 Log.w(TAG, "in onBind"); 14 return mServerMessenger.getBinder(); 15 } 16
17 class ServerHandler extends Handler { 18 @Override 19 public void handleMessage(Message msg) { 20 Log.w(TAG, "thread name:" + Thread.currentThread().getName()); 21 switch (msg.what) { 22 case MSG_FROM_CLIENT_TO_SERVER: 23 Log.w(TAG, "receive msg from client"); 24 mClientMessenger = msg.replyTo; 25
26 // service發送消息給client
27 Message toClientMsg = Message.obtain(null, MSG_FROM_SERVER_TO_CLIENT); 28 try { 29 Log.w(TAG, "server begin send msg to client"); 30 mClientMessenger.send(toClientMsg); 31 } catch (RemoteException e) { 32 e.printStackTrace(); 33 } 34 break; 35 default: 36 super.handleMessage(msg); 37 } 38 } 39 } 40
41 @Override 42 public boolean onUnbind(Intent intent) { 43 Log.w(TAG, "in onUnbind"); 44 return super.onUnbind(intent); 45 } 46
47 @Override 48 public void onDestroy() { 49 Log.w(TAG, "in onDestroy"); 50 super.onDestroy(); 51 } 52 }
1 public class CActivity extends Activity { 2
3 public static final String TAG = "CActivity"; 4
5 private Button bindServiceBtn; 6 private Button unbindServiceBtn; 7 private Button sendMsgToServerBtn; 8
9 private ServiceConnection sc = new MyServiceConnection(); 10 private boolean mBound; 11
12 private Messenger mServerMessenger; 13
14 private Handler mClientHandler = new MyClientHandler(); 15 private Messenger mClientMessenger = new Messenger(mClientHandler); 16
17 private class MyClientHandler extends Handler { 18 @Override 19 public void handleMessage(Message msg) { 20 if (msg.what == MyMessengerService.MSG_FROM_SERVER_TO_CLIENT) { 21 Log.w(TAG, "reveive msg from server"); 22 } 23 } 24 } 25
26 private class MyServiceConnection implements ServiceConnection { 27
28 @Override 29 public void onServiceConnected(ComponentName name, IBinder binder) { 30 Log.w(TAG, "in MyServiceConnection onServiceConnected"); 31 mServerMessenger = new Messenger(binder); 32
33 mBound = true; 34 } 35
36 @Override 37 public void onServiceDisconnected(ComponentName name) { 38 // This is called when the connection with the service has been 39 // unexpectedly disconnected -- that is, its process crashed.
40 Log.w(TAG, "in MyServiceConnection onServiceDisconnected"); 41
42 mBound = false; 43 } 44 } 45
46 @Override 47 protected void onCreate(Bundle savedInstanceState) { 48 super.onCreate(savedInstanceState); 49 setContentView(R.layout.c); 50
51 bindServiceBtn = (Button) findViewById(R.id.bind_service); 52 unbindServiceBtn = (Button) findViewById(R.id.unbind_service); 53 sendMsgToServerBtn = (Button) findViewById(R.id.send_msg_to_server); 54
55 bindServiceBtn.setOnClickListener(new View.OnClickListener() { 56 @Override 57 public void onClick(View v) { 58 Intent intent = new Intent(CActivity.this, MyMessengerService.class); 59 bindService(intent, sc, Context.BIND_AUTO_CREATE); 60 } 61 }); 62
63 unbindServiceBtn.setOnClickListener(new View.OnClickListener() { 64 @Override 65 public void onClick(View v) { 66 excuteUnbindService(); 67 } 68 }); 69
70 sendMsgToServerBtn.setOnClickListener(new View.OnClickListener() { 71 @Override 72 public void onClick(View v) { 73 sayHello(); 74 } 75 }); 76
77 new Handler().postDelayed(new Runnable() { 78 @Override 79 public void run() { 80 Intent intent = new Intent(CActivity.this, MyAlarmBroadcastReceiver.class); 81 sendBroadcast(intent); 82 } 83 }, 3 * 1000); 84
85 } 86
87 public void sayHello() { 88 if (!mBound) 89 return; 90 // Create and send a message to the service, using a supported 'what' value
91 Message msg = Message.obtain(null, MyMessengerService.MSG_FROM_CLIENT_TO_SERVER, 0, 0); 92 // 經過replyTo把client端的Messenger(信使)傳遞給service
93 msg.replyTo = mClientMessenger; 94 try { 95 mServerMessenger.send(msg); 96 } catch (RemoteException e) { 97 e.printStackTrace(); 98 } 99 } 100
101 private void excuteUnbindService() { 102 if (mBound) { 103 unbindService(sc); 104 mBound = false; 105 } 106 } 107
108 @Override 109 protected void onDestroy() { 110 super.onDestroy(); 111 Log.w(TAG, "in onDestroy"); 112 excuteUnbindService(); 113 } 114 }
其中,須要注意的幾點是:
1.MyMessengerService自定中,經過new Messenger(new ServerHandler())建立Messenger對象,在onBind(..)回調中,經過調用Messenger對象的getBinder()方法,將Binder返回;
2.Client在ServiceConnection的onServiceConnected(..)的回調中,經過new Messenger(binder)獲取到Service傳遞過來的mServerMessenger;
3.接下來,就能夠經過mServerMessenger.send(msg)方法向Service發送message,Service中的Messenger構造器中的Handler便可接收到此信息,在handleMessage(..)回調中處理;
4.至此只是完成了從Client發送消息到Service,一樣的道理,想實現Service發送消息到Client,能夠在客戶端定義一個Handler,並獲得相應的Messenger,在Clinet發送消息給Service時,經過msg.replyTo = mClientMessenger方式將Client信使傳遞給Service;
5.Service接收到Client信使後,獲取此信使,並經過mClientMessenger.send(toClientMsg)方式將Service消息發送給Client。
至此,完成了Client - Service之間的雙向通訊流程。
3).AIDL(Android Interface Definition Language)
通常狀況下,Messenger這種方式都是能夠知足需求的,固然,經過自定義AIDL方式相對更加靈活。
這種方式須要本身在項目中自定義xxx.aidl文件,而後系統會自動在gen目錄下生成相應的接口類文件,接下來整個的流程與Messenger方式差異不大,網上也有很多實例,在此再也不具體給出。
注:不管哪一種方式的Bound Service,在進行unbind(..)操做時,都須要注意當前Service是否處於已經綁定狀態,不然可能會由於當前Service已經解綁後繼續執行unbind(..)會致使崩潰。這點與Started Service區別很大(如前文所述:stopService(..)無需作當前Service是否有效的判斷)。
4.Local Service VS Remote Service
Local Service:很多人又稱之爲」本地服務「,是指Client - Service同處於一個進程;
Remote Service:又稱之爲」遠程服務「,通常是指Service處於單獨的一個進程中。
其餘使用上上文中基本上都有所述。
5.Service特性
1.Service自己都是運行在其所在進程的主線程(若是Service與Clinet同屬於一個進程,則是運行於UI線程),但Service通常都是須要進行」長期「操做,因此常常寫法是在自定義Service中處理」長期「操做時須要新建線程,以避免阻塞UI線程或致使ANR;
2.Service一旦建立,須要中止時都須要顯示調用相應的方法(Started Service須要調用stopService(..)或Service自己調用stopSelf(..), Bound Service須要調用unbindService(..)),不然對於Started Service將處於一直運行狀態,對於Bound Service,當Client生命週期結束時也將所以問題。也就是說,Service執行完畢後,必須人爲的去中止它。
6.IntentService
IntentService是系統提供給咱們的一個已經繼承自Service類的特殊類,IntentService特殊性是相對於Service自己的特性而言的:
1.默認直接實現了onBind(..)方法,直接返回null,並定義了抽象方法onHandlerIntent(..),用戶自定義子類時,須要實現此方法;
2.onHandlerIntent(..)主要就是用來處於相應的」長期「任務的,而且已經自動在新的線程中,用戶無語自定義新線程;
3.當」長期「任務執行完畢後(也就是onHandlerIntent(..)執行完畢後),此IntentService將自動結束,無需人爲調用方法使其結束;
4.IntentService處於任務時,也是按照隊列的方式一個個去處理,而非真正意義上的多線程併發方式。
下面是一個基本的繼承自IntentService的自定義Service:
1 public class MyIntentService extends IntentService { 2
3 public static final String TAG = "MyIntentService"; 4
5 public MyIntentService() { 6 super(TAG); 7 } 8
9 public MyIntentService(String name) { 10 super(name); 11 } 12
13 @Override 14 protected void onHandleIntent(Intent intent) { 15 Log.w(TAG, "in onHandleIntent"); 16 Log.w(TAG, "thread name:" + Thread.currentThread().getName()); 17 } 18
19 }
7.前臺Service
Android中Service接口中還提供了一個稱之爲」前臺Service「的概念。經過Service.startForeground (int id, Notification notification)方法能夠將此Service設置爲前臺Service。在UI顯示上,notification將是一個處於onGoing狀態的通知,使得前臺Service擁有更高的進程優先級,而且Service能夠直接notification通訊。
下面是一個簡單的前臺Service使用實例:
1 public class MyService extends Service { 2
3 public static final String TAG = "MyService"; 4
5 @Override 6 public IBinder onBind(Intent intent) { 7 return null; 8 } 9
10 @Override 11 public void onCreate() { 12 super.onCreate(); 13 Log.w(TAG, "in onCreate"); 14 } 15
16 @Override 17 public int onStartCommand(Intent intent, int flags, int startId) { 18 Log.w(TAG, "in onStartCommand"); 19 Log.w(TAG, "MyService:" + this); 20 String name = intent.getStringExtra("name"); 21 Log.w(TAG, "name:" + name); 22
23
24 Notification notification = new Notification(R.drawable.ic_launcher, "test", System.currentTimeMillis()); 25 Intent notificationIntent = new Intent(this, DActivity.class); 26 PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntesnt, 0); 27 notification.setLatestEventInfo(this, "title", "content", pendingIntent); 28 startForeground(1, notification); 29
30
31 return START_REDELIVER_INTENT; 32 } 33
34 @Override 35 public void onDestroy() { 36 super.onDestroy(); 37 Log.w(TAG, "in onDestroy"); 38 } 39 }