Android基礎 : Android Service[轉]

不少狀況下,一些與用戶不多須要產生交互的應用程序,咱們通常讓它們在後臺運行就好了,並且在它們運行期間咱們仍然能運行其餘的應用。

爲了處理這種後臺進程,Android引入了Service的概念。Service在Android中是一種長生命週期的組件,它不實現任何用戶界面。最多見的例子如:媒體播放器程序,它能夠在轉到後臺運行的時候仍然能保持播放歌曲;或者如文件下載程序,它能夠在後臺執行文件的下載。

讓咱們來看下如何建立Service:
建立一個Service
Android中已經定義了一個 ‘Service’類,全部其餘的Service都繼承於該類。Service類中定義了一系列的生命週期相關的方法,如: onCreate(), onStart(), onDestroy()。參見下例:

 

package com.wissen.testApp.service;php

public class MyService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }java

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(this, 「Service created…」, Toast.LENGTH_LONG).show();
    }android

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this, 「Service destroyed…」, Toast.LENGTH_LONG).show();
    }
}eclipse

 

上例中的這個Service主要作了這些事:當服務建立和銷燬時經過界面消息提示用戶。
如Android中的其它部件同樣, Service也會和一系列Intent關聯。Service的運行入口須要在AndroidManifest.xml中進行配置,以下:ide

 


   
       
   

 

 

以後咱們的Service就能夠被其餘代碼所使用了。

使用Service:
應用程序能夠經過調用 Context.startService方法來啓動Service。若是當前沒有指定的Service實例被建立,則該方法會調用 Service的onCreate方法來建立一個實例;不然調用Service的onStart方法。參見下列代碼:

 

 

..
Intent serviceIntent = new Intent();
serviceIntent.setAction(」com.wissen.testApp.service.MY_SERVICE」);
startService(serviceIntent);
..工具

 

以上代碼調用了startService方法,Service會持續運行,直到調用stopService()或stopSelf()方法。
還有另外一種綁定Service的方式:this

 


ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        Log.i(」INFO」, 「Service bound 「);
    }插件

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
         Log.i(」INFO」, 「Service Unbound 「);
    }
};xml

bindService(new Intent(」com.wissen.testApp.service.MY_SERVICE」), conn, Context.BIND_AUTO_CREATE);
對象

 

當應用程序綁定一個Service後,該應用程序和Service之間就能進行互相通訊,一般,這種通訊的完成依靠於咱們定義的一些接口,請看下例:

 

package com.wissen.testApp;

public interface IMyService {
    public int getStatusCode();
}

這裏定義了一個方法來獲取Service的狀態,可是Service是如何來使它起做用的呢?以前咱們看到Service中有個返回IBinder對象的onBind方法,這個方法會在Service被綁定到其餘程序上時被調用,而這個IBinder對象和以前看到的onServiceConnected方法中傳入的那個IBinder是同一個東西。應用和Service間就依靠這個IBinder對象進行通訊:
public class MyService extends Service {
    private int statusCode;
    private MyServiceBinder myServiceBinder = new MyServiceBinder();
   
    @Override
    public IBinder onBind(Intent intent) {
        return myServiceBinder;
    }
    public class MyServiceBinder extends Binder implements IMyService {
        public int getStatusCode() {
             return statusCode;
       }
    }
   
    …
}
 下列代碼是說明getStatusCode是如何被調用的:  
ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        IMyService myService = (IMyService) service;
        statusCode = myService.getStatusCode();
        Log.i(」INFO」, 「Service bound 「);
    }
   
    …
};
或者,你也能夠經過使用ServiceListener接口來達成相同的目的。

與遠程Service通訊(進程間Service通訊):
如何兩個進程間的Service須要進行通訊,則須要把對象序列化後進行互相發送。
Android提供了一個 AIDL (Android接口定義語言)工具來處理序列化和通訊。這種狀況下Service須要以aidl文件的方式提供服務接口,AIDL工具將生成一個相應的java接口,而且在生成的服務接口中包含一個功能調用的stub服務樁類。Service的實現類須要去繼承這個 stub服務樁類。Service的onBind方法會返回實現類的對象,以後你就可使用它了,參見下例:
先建立一個IMyRemoteService.aidl文件,內容以下:

 

package com.wissen.testApp;

interface IMyRemoteService {
    int getStatusCode();
}

 

若是你正在使用eclipse的 Android插件,則它會根據這個aidl文件生成一個Java接口類。生成的接口類中會有一個內部類Stub類,你要作的事就是去繼承該Stub類:

 

package com.wissen.testApp;

class RemoteService implements Service {
    int statusCode;
   
    @Override
    public IBinder onBind(Intent arg0) {
        return myRemoteServiceStub;
    }

    private IMyRemoteService.Stub myRemoteServiceStub = new IMyRemoteService.Stub() {
        public int getStatusCode() throws RemoteException {
            return 0;
        }
    };
   
    …
}

 

當客戶端應用鏈接到這個Service時,onServiceConnected方法將被調用,客戶端就能夠得到IBinder對象。參看下面的客戶端onServiceConnected方法:

 


ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        IMyRemoteService myRemoteService = IMyRemoteService.Stub.asInterface(service);
        try {
            statusCode = myRemoteService.getStatusCode();
       } catch(RemoteException e) {
           // handle exception
       }
        Log.i(」INFO」, 「Service bound 「);
    }
   
    …
};

 

權限:
咱們能夠在AndroidManifest.xml文件中使用 標籤來指定Service訪問的權限:

 


   
       
   

 

以後應用程序要訪問該Service的話就須要使用 標籤來指定相應的權限:

相關文章
相關標籤/搜索