Android中的Service詳解
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
今天我們就來介紹一下Android中的四大元件中的服務Service,說到Service,
它分為本地服務和遠端服務:區分這兩種服務就是看客戶端和服務端是否在同一個程序中,本地服務是在同一程序中的,遠端服務是不在同一個程序中的。
開啟服務也有兩種方式,一種是startService(),他對應的結束服務的方法是stopService(),另一種是bindService(),結束服務的是unBindService(),這兩種方式的區別就是:當客戶端Client使用startService方法開啟服務的時候,這個服務和Client之間就沒有聯絡了,Service的執行和Client是相互獨立的,想結束這個服務的話,就在服務本身中呼叫stopSelf()方法結束服務。而當客戶端Client使用bindService方法開始服務的時候,這個服務和Client是一種關聯的關係,他們之間使用Binder的代理物件進行互動,這個在後面會詳細說到,要是結束服務的話,需要在Client中和服務斷開,呼叫unBindService方法。
在這裡我們只做bindService方式的研究,而startService方式比較獨立和簡單,這裡就不做演示了。
首先來說一下本地服務:
本地服務很簡單的,就是Client和這個服務在同一個程序中:
先來看一下程式碼吧:
下面這張圖是專案的結構圖:
為了方便資料的訪問,這裡定義一個數據的訪問介面:
[java] view plain copy- package com.nativeservice.demo;
- /**
- * 訪問介面
- * @author weijiang204321
- */
- public interface IStudent {
- /**
- * 通過no訪問name
- * @param no
- * @return
- */
- public String getNameByNumber(int no);
- }
下面再來看一下StudentService的程式碼:
[java] view plain copy- package com.nativeservice.demo;
- import android.app.Service;
- import android.content.Intent;
- import android.os.Binder;
- import android.os.IBinder;
- /**
- * 定義的服務Service
- * @author weijiang204321
- */
- public class StudentService extends Service{
- //名稱
- public static String[] nameAry = {"張飛","李小龍","趙薇"};
- /**
- * 通過no獲取name
- * @param no
- * @return
- */
- private String getNameByNo(int no){
- if(no>0 && no<4)
- return nameAry[no-1];
- return null;
- }
- @Override
- public IBinder onBind(Intent arg0) {
- return new StudentBinder();
- }
- /**
- * 自定義的Binder物件
- * @author weijiang204321
- *
- */
- private class StudentBinder extends Binder implements IStudent{
- @Override
- public String getNameByNumber(int no) {
- return getNameByNo(no);
- }
- }
- }
下面看一下Client程式碼:
[java] view plain copy- package com.nativeservice.demo;
- import android.app.Activity;
- import android.content.ComponentName;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.os.Bundle;
- import android.os.IBinder;
- import android.os.Looper;
- import android.widget.Toast;
- /**
- * 測試Service
- * @author weijiang204321
- *
- */
- public class MainActivity extends Activity {
- private IStudent student;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //開啟查詢名稱的服務
- Intent service = new Intent(this,StudentService.class);
- bindService(service,new StudentConnection(),BIND_AUTO_CREATE);
- //延遲2s在顯示查詢的內容,不然開啟服務也是需要時間的,如果不延遲一段時間的話,student物件為null;
- new Thread(){
- @Override
- public void run(){
- try {
- Thread.sleep(2*1000);
- Looper.prepare();
- Toast.makeText(getApplicationContext(), student.getNameByNumber(1), Toast.LENGTH_LONG).show();
- Looper.loop();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }.start();
- }
- /**
- * 自定義的服務連線connection
- * @author weijiang204321
- *
- */
- private class StudentConnection implements ServiceConnection{
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- student = (IStudent)service;
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- }
- }
- }
StudentConnection,必須實現兩個方法,這兩個方法見名思議,一個是連線時呼叫的方法,一個是斷開連線時的方法,在開始連線的方法onServiceConnected中傳回來一個IBinder物件,這個時候需要將其轉化一下,這個就是為什麼要在開始的時候定義一個IStudent介面,在這裡訪問資料就方便了,同時在Client程式碼中要做個延遲的操作來訪問資料,因為開啟服務,連線這個過程是需要時間的,所以在這裡就延遲了2s,這裡只是為了能夠正常顯示資料,才這麼做的,不然student物件是為null的,當然要根據自己的實際情況操作。最後還要在AndroidMainfest.xml中配置Service:
[html] view plain copy