一、Service 簡介
首先我們先了解一下Service
的繼承關系,方便我們更好的了解Service
。Service
繼承關系如下:
java.lang.Object
? android.content.Context
? android.content.ContextWrapper
? android.app.Service
Service
是Android
四大組件之一(Activity
活動,Service
服務,ContentProvider
內容提供者,BroadcastReceiver
廣播),與Activity
相比,Service
是運行在后臺,無用戶界面,用戶無法看到,Activity
則是運行在前臺,用戶可以看得見。
Service
主要用于組件之間交互(例如:與Activity
、ContentProvider
、BroadcastReceiver
進行交互)、執行后臺任務等(例如下載文件,播放音樂等)。
注意:Service
在主線程運行時長不能超過20s
,否則會出現ANR
,耗時操作一般建議在子線程或工作線程中進行操作。
二、Service 的注冊
Service
是四大組件之一,必現在AndroidMainfest.xml
中注冊。Service
注冊方法如下:
... >
...
... >
android:name=".ServiceMethods" />
...
>
>
注意:Service
如不注冊 ,不會像Activity
那樣會導致App Crash
,Service
不注冊 不會報異常信息,但是服務會起不來,如不注意很容易迷惑。
三、Service 的啟動模式
Service
啟動模式主要分兩種:1. 啟動模式。2. 綁定模式。
-
1.啟動模式
此模式通過startService()
方法啟動,此服務可以在后臺一直運行,不會隨啟動組件的消亡而消亡。
但是,此種啟動模式只能執行單一操作,并且無法返回結果給調用方,主要常用于網絡下載、上傳文件,播放音樂等。
-
2.綁定模式
此模式通過綁定組件(Activity
等)調用bindService()
啟動,此服務隨綁定組件的消亡而解除綁定。
如果此時沒有其它通過startService()
啟動,則此服務會隨綁定組件的消亡而消亡。
多個組件不僅可以同時綁定一個Service
,而且可以通過進程間通信(IPC)
執行跨進程操作等。
-
3.兩種服務可以同時運行
啟動模式與綁定模式的服務可以同時運行,在銷毀服務時,只有兩種模式都不在使用Service
時候,才可以銷毀服務,否則會引起異常。
四、Service的生命周期
Service
有兩種不同的啟動模式 ,不同的啟動模式對應不同生命周期。兩種不同Service
模式的生命周期如下:
兩種 Service 模式生命周期圖
五、啟動模式使用舉例
通過啟動模式啟動的Service
,如不主動關閉,Service
會一直在。
1.啟動模式啟動服務的方法
Intent mBindIntent = new Intent(ServiceMethods.this, BindServiceMethods.class);
startService(mStartIntent);
2.啟動模式啟動服務的生命周期
下面是驗證啟動模式啟動服務的生命周期的方法,詳細生命周期請查看上方Service
的生命周期圖。
01-03 17:16:36.147 23789-23789/com.android.program.programandroid I/StartService wjwj:: ----onCreate----
01-03 17:16:36.223 23789-23789/com.android.program.programandroid I/StartService wjwj:: ----onStartCommand----
01-03 17:16:38.174 23789-23789/com.android.program.programandroid I/StartService wjwj:: ----onDestroy----
3.啟動模式 啟動服務案例
此案例功能:啟動服務,在服務中創建通知
// Service 創建方法
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "----onCreate----");
}
// Service 啟動方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "----onStartCommand----");
// 獲取NotificationManager實例
notifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// 實例化NotificationCompat.Builder并設置相關屬性
NotificationCompat.Builder builder = new NotificationCompat.Builder(
this)
// 設置小圖標
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(
BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher))
// 設置通知標題
.setContentTitle("我是通過StartService服務啟動的通知")
// 設置通知不能自動取消
.setAutoCancel(false).setOngoing(true)
// 設置通知時間,默認為系統發出通知的時間,通常不用設置
// .setWhen(System.currentTimeMillis())
// 設置通知內容
.setContentText("請使用StopService 方法停止服務");
// 通過builder.build()方法生成Notification對象,并發送通知,id=1
notifyManager.notify(1, builder.build());
return super.onStartCommand(intent, flags, startId);
}
// Service 銷毀方法
@Override
public void onDestroy() {
Log.i(TAG, "----onDestroy----");
notifyManager.cancelAll();
super.onDestroy();
}
六、 綁定服務介紹
綁定模式啟動的服務會隨著綁定逐漸的消亡而解除Service
綁定,如果此時Service
沒有通過啟動模式啟動,則此服務將會被銷毀。
1.啟動綁定模式服務的方法
綁定模式,是通過其他組件調用bindService()
方法啟動的Service
。
// 啟動綁定服務處理方法
public void BtnStartBindService(View view) {
// 啟動綁定服務處理方法
bindService(mBindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
isBindService = true;
Toast.makeText(ServiceMethod.this, "啟動 " + mBindCount + " 次綁定服務",
Toast.LENGTH_SHORT).show();
}
public void BtnSopBindService(View view) {
if (isBindService) {
// 解除綁定服務處理方法
unbindService(serviceConnection);
Toast.makeText(ServiceMethod.this, "解除 " + mUnBindCount + " 次綁定服務",
Toast.LENGTH_SHORT).show();
isBindService = false;
}
}
2.綁定服務 隨綁定組件的消亡而消亡
如果綁定服務的組件被destory
,這 bind 服務會走到onUnbind()
方法。
3. 綁定模式 生命周期回調代碼如下:
// Service 創建方法
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "----onCreate----");
}
// Service 綁定方法
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "----onBind----");
MyBinder myBinder = new MyBinder();
return myBinder;
}
// Service 解除綁定方法
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "----onUnbind----");
return super.onUnbind(intent);
}
// Service 銷毀方法
@Override
public void onDestroy() {
Log.i(TAG, "----onDestroy----");
super.onDestroy();
}
綁定服務的生命周期代碼打印Log
信息如下:
01-03 20:32:59.422 13306-13306/com.android.program.programandroid I/BindService wjwj:: ----onCreate----
01-03 20:32:59.423 13306-13306/com.android.program.programandroid I/BindService wjwj:: -----onBind-----
01-03 20:33:09.265 13306-13306/com.android.program.programandroid I/BindService wjwj:: ----onUnbind----
01-03 20:33:09.266 13306-13306/com.android.program.programandroid I/BindService wjwj:: ----onDestroy----
七、bind 服務舉例
功能:
獲取綁定模式啟動 綁定服務及解除綁定服務的次數
1.綁定服務類
package com.android.program.programandroid.component.Service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class BindServiceMethods extends Service {
private static final String TAG = "BindService wjwj:";
public BindServiceMethods() {
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "----onCreate----");
}
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "----onBind----");
MyBinder myBinder = new MyBinder();
return myBinder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "----onUnbind----");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
Log.i(TAG, "----onDestroy----");
super.onDestroy();
}
}
2.組件與綁定服務類之間的交互
// 啟動綁定服務處理方法
public void BtnStartBindService(View view) {
bindService(mBindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
isBindService = true;
Toast.makeText(ServiceMethods.this,"啟動 "+mBindCount+" 次綁定服務",Toast.LENGTH_SHORT).show();
}
// 解除綁定服務處理方法
public void BtnSopBindService(View view) {
if (isBindService) {
unbindService(serviceConnection);
Toast.makeText(ServiceMethods.this,"解除 "+mUnBindCount+" 次綁定服務",Toast.LENGTH_SHORT).show();
isBindService=false;
}
}
3.組件之間交互所需的Binder
接口類
/**
* 該類提供 綁定組件與綁定服務提供接口
* */
public class MyBinder extends Binder {
private int count = 0;
public int getBindCount() {
return ++count;
}
public int getUnBindCount() {
return count> 0 ? count-- : 0;
}
}
八、服務的優先級
服務默認啟動方式是后臺服務,但是可以通過設置服務為前臺服務,提高服務的優先級,進而避免手機內存緊張時,服務進程被殺掉。
設置服務優先級的方法如下:
1.設置為前臺服務
//設置為前臺服務
startForeground(int, Notification)
2.取消前臺服務
//取消為前臺服務
stopForeground(true);
3.startForeground 前臺服務案例
功能:前臺服務綁定通知信息,提高服務進程優先級,否則取消通知信息
package com.android.program.programandroid.component.Service;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import com.android.program.programandroid.R;
public class MyStartForcegroundService extends Service {
public MyStartForcegroundService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals("start_forceground_service")) {
// 獲取NotificationManager實例
NotificationManager notifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// 實例化NotificationCompat.Builder并設置相關屬性
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
// 設置小圖標
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
// 設置通知標題
.setContentTitle("我是通過startForeground 啟動前臺服務通知")
// 設置通知不能自動取消
.setAutoCancel(false)
.setOngoing(true)
// 設置通知時間,默認為系統發出通知的時間,通常不用設置
// .setWhen(System.currentTimeMillis())
// 設置通知內容
.setContentText("請使用stopForeground 方法改為后臺服務");
//通過builder.build()方法生成Notification對象,并發送通知,id=1
// 設置為前臺服務
startForeground(1, builder.build());
} else if (intent.getAction().equals("stop_forceground_service")) {
stopForeground(true);
}
return super.onStartCommand(intent, flags, startId);
}
}
審核編輯 :李倩
-
Service
+關注
關注
0文章
30瀏覽量
13784 -
組件
+關注
關注
1文章
512瀏覽量
17817 -
線程
+關注
關注
0文章
504瀏覽量
19677
原文標題:八、服務的優先級
文章出處:【微信號:哆啦安全,微信公眾號:哆啦安全】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論