
2.具體使用解析
2.1 本地Service
這是最普通、最常用的背景服務Service。
2.1.1 使用步驟
- 步驟1:建立子類繼承Service類
需重寫父類的onCreate()、onStartCommand()、onDestroy()和onBind()方法
- 步驟2:建構用于啟動Service的Intent對象
- 步驟3:調用startService()啟動Service、調用stopService()停止服務
- 步驟4:在AndroidManifest.xml裡注冊Service
例子:
需重寫父類的onCreate()、onStartCommand()、onDestroy()和onBind()
public class MyService extends Service {
//啟動Service之後,就可以在onCreate()或onStartCommand()方法裡去執行一些具體的邏輯
//由于這裡作Demo用,是以隻列印一些語句
@Override
public void onCreate() {
super.onCreate();
System.out.println("執行了onCreat()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("執行了onStartCommand()");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("執行了onDestory()");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
步驟2:在主布局檔案設定兩個Button分别用于啟動和停止Service
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="scut.carson_ho.demo_service.MainActivity">
<Button
android:layout_centerInParent="true"
android:id="@+id/startService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="啟動服務" />
<Button
android:layout_centerInParent="true"
android:layout_below="@+id/startService"
android:id="@+id/stopService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止服務" />
</RelativeLayout>
步驟3:建構Intent對象,并調用startService()啟動Service、stopService停止服務
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button startService;
private Button stopService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService = (Button) findViewById(R.id.startService);
stopService = (Button) findViewById(R.id.stopService);
startService.setOnClickListener(this);
startService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//點選啟動Service Button
case R.id.startService:
//建構啟動服務的Intent對象
Intent startIntent = new Intent(this, MyService.class);
//調用startService()方法-傳入Intent對象,以此啟動服務
startService(startIntent);
//點選停止Service Button
case R.id.stopService:
//建構停止服務的Intent對象
Intent stopIntent = new Intent(this, MyService.class);
//調用stopService()方法-傳入Intent對象,以此停止服務
stopService(stopIntent);
}
}
}
AndroidManifest.xml
2.2 可通信的服務Service
- 上面介紹的Service是最基礎的,但隻能單機使用,即無法與Activity通信
- 接下來将在上面的基礎用法上,增設“與Activity通信”的功能,即使用綁定Service服務(Binder類、bindService()、onBind()、unbindService()、onUnbind())
2.2.1 執行個體Demo
接下來我将用一個執行個體Demo進行可通信的服務Service說明
- 步驟1:在建立子類繼承Service類,并建立一個子類繼承自Binder類、寫入與Activity關聯需要的方法、建立執行個體
public class MyService extends Service {
private MyBinder mBinder = new MyBinder();
@Override
public void onCreate() {
super.onCreate();
System.out.println("執行了onCreat()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("執行了onStartCommand()");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
System.out.println("執行了onDestory()");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
System.out.println("執行了onBind()");
//傳回執行個體
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
System.out.println("執行了onUnbind()");
return super.onUnbind(intent);
}
//建立一個子類繼承自Binder類
class MyBinder extends Binder {
public void service_connect_Activity() {
System.out.println("Service關聯了Activity,并在Activity執行了Service的方法");
}
}
}
步驟2:在主布局檔案再設定兩個Button分别用于綁定和解綁Service
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="scut.carson_ho.demo_service.MainActivity">
<Button
android:layout_centerInParent="true"
android:id="@+id/startService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="啟動服務" />
<Button
android:layout_centerInParent="true"
android:layout_below="@+id/startService"
android:id="@+id/stopService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止服務" />
<Button
android:layout_centerInParent="true"
android:layout_below="@id/stopService"
android:id="@+id/bindService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="綁定服務" />
<Button
android:layout_centerInParent="true"
android:layout_below="@id/bindService"
android:id="@+id/unbindService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="解綁服務"
/>
</RelativeLayout>
步驟3:在Activity通過調用MyBinder類中的public方法來實作Activity與Service的聯系
即實作了Activity指揮Service幹什麼Service就去幹什麼的功能
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button startService;
private Button stopService;
private Button bindService;
private Button unbindService;
private MyService.MyBinder myBinder;
//建立ServiceConnection的匿名類
private ServiceConnection connection = new ServiceConnection() {
//重寫onServiceConnected()方法和onServiceDisconnected()方法
//在Activity與Service建立關聯和解除關聯的時候調用
@Override
public void onServiceDisconnected(ComponentName name) {
}
//在Activity與Service解除關聯的時候調用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//執行個體化Service的内部類myBinder
//通過向下轉型得到了MyBinder的執行個體
myBinder = (MyService.MyBinder) service;
//在Activity調用Service類的方法
myBinder.service_connect_Activity();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService = (Button) findViewById(R.id.startService);
stopService = (Button) findViewById(R.id.stopService);
startService.setOnClickListener(this);
stopService.setOnClickListener(this);
bindService = (Button) findViewById(R.id.bindService);
unbindService = (Button) findViewById(R.id.unbindService);
bindService.setOnClickListener(this);
unbindService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//點選啟動Service
case R.id.startService:
//建構啟動服務的Intent對象
Intent startIntent = new Intent(this, MyService.class);
//調用startService()方法-傳入Intent對象,以此啟動服務
startService(startIntent);
break;
//點選停止Service
case R.id.stopService:
//建構停止服務的Intent對象
Intent stopIntent = new Intent(this, MyService.class);
//調用stopService()方法-傳入Intent對象,以此停止服務
stopService(stopIntent);
break;
//點選綁定Service
case R.id.bindService:
//建構綁定服務的Intent對象
Intent bindIntent = new Intent(this, MyService.class);
//調用bindService()方法,以此停止服務
bindService(bindIntent,connection,BIND_AUTO_CREATE);
//參數說明
//第一個參數:Intent對象
//第二個參數:上面建立的Serviceconnection執行個體
//第三個參數:标志位
//這裡傳入BIND_AUTO_CREATE表示在Activity和Service建立關聯後自動建立Service
//這會使得MyService中的onCreate()方法得到執行,但onStartCommand()方法不會執行
break;
//點選解綁Service
case R.id.unbindService:
//調用unbindService()解綁服務
//參數是上面建立的Serviceconnection執行個體
unbindService(connection);
break;
default:
break;
}
}
}
2.3 前台Service
前台Service和背景Service(普通)最大的差別就在于:
- 前台Service在下拉通知欄有顯示通知(如下圖),但背景Service沒有;
TT9$TN8IK1SAPDT%~0IRLS2.png
- 前台Service優先級較高,不會由于系統記憶體不足而被回收;背景Service優先級較低,當系統出現記憶體不足情況時,很有可能會被回收
2.3.1 具體使用
用法很簡單,隻需要在原有的Service類對onCreate()方法進行稍微修改即可,如下圖:
@Override
public void onCreate() {
super.onCreate();
System.out.println("執行了onCreat()");
//添加下列代碼将背景Service變成前台Service
//建構"點選通知後打開MainActivity"的Intent對象
Intent notificationIntent = new Intent(this,MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);
//建立Builer對象
Notification.Builder builer = new Notification.Builder(this);
builer.setContentTitle("前台服務通知的标題");//設定通知的标題
builer.setContentText("前台服務通知的内容");//設定通知的内容
builer.setSmallIcon(R.mipmap.ic_launcher);//設定通知的圖示
builer.setContentIntent(pendingIntent);//設定點選通知後的操作
Notification notification = builer.getNotification();//将Builder對象轉變成普通的notification
startForeground(1, notification);//讓Service變成前台Service,并在系統的狀态欄顯示出來
}
2.3.2 測試結果
運作後,當點選Start Service或Bind Service按鈕,Service就會以前台Service的模式啟動(通知欄上有通知),如下圖
點選啟動服務
2.4 遠端Service
具體請看我寫的另外一篇文章:Android:遠端服務Service(含AIDL & IPC講解)
3. 使用場景
- 通過上述描述,你應該對Service類型及其使用非常了解;
- 那麼,我們該什麼時候用哪種類型的Service呢?
- 各種Service的使用場景請看下圖: