天天看點

android service 元件

<b>Service</b><b>概念及用途</b><b>:</b>

Android中的服務,它與Activity不同,它是不能與使用者互動的,不能自己啟動的,運作在背景的程式,如果我們退出應用時,Service程序并沒有結束,它仍然在背景運作,那 我們什麼時候會用到Service呢?比如我們播放音樂的時候,有可能想邊聽音樂邊幹些其他事情,當我們退出播放音樂的應用,如果不用Service,我 們就聽不到歌了,是以這時候就得用到Service了,又比如當我們一個應用的資料是通過網絡擷取的,不同時間(一段時間)的資料是不同的這時候我們可以 用Service在背景定時更新,而不用每打開應用的時候在去擷取。

<b>Service</b><b>生命周期</b> :

Android Service的生命周期并不像Activity那麼複雜,它隻繼承了onCreate(),onStart(),onDestroy()三個方法,當我們第一次啟動Service時,先後調用了onCreate(),onStart()這兩個方法,當停止Service時,則執行onDestroy()方法,這裡需要注意的是,如果Service已經啟動了,當我們再次啟動Service時,不會在執行onCreate()方法,而是直接執行onStart()方法,具體的可以看下面的執行個體。

<b>Service</b><b>與</b><b>Activity</b><b>通信</b><b>:</b>

Service後端的資料最終還是要呈現在前端Activity之上的,因為啟動Service時,系統會重新開啟一個新的程序,這就涉及到不同程序間通信的問題了(AIDL)這一節我不作過多描述,當我們想擷取啟動的Service執行個體時,我們可以用到bindService和onBindService方法,它們分别執行了Service中IBinder()和onUnbind()方法。

Service的類型

Service有兩種類型:

1. 本地服務(Local Service):用于應用程式内部

2. 遠端服務(Remote Sercie):用于android系統内部的應用程式之間

前者用于實作應用程式自己的一些耗時任務,比如查詢更新資訊,并不占用應用程式比如Activity所屬線程,而是單開線程背景執行,這樣使用者體驗比較好。

後者可被其他應用程式複用,比如天氣預報服務,其他應用程式不需要再寫這樣的服務,調用已有的即可。

執行個體一

示範如何建立、啟動、停止及綁定一個service

程式檔案

/Chapter07_Service_Example/src/com/amaker/ch07/app/MainActivity.java

代碼  

package com.amaker.ch07.app;  

import com.amaker.ch07.app.R;  

import android.app.Activity;  

import android.app.Service;  

import android.content.ComponentName;  

import android.content.Intent;  

import android.content.ServiceConnection;  

import android.os.Bundle;  

import android.os.IBinder;  

import android.util.Log;  

import android.view.View;  

import android.view.View.OnClickListener;  

import android.widget.Button;  

import android.widget.Toast;  

/**  

 * 測試Service  

 */ 

public class MainActivity extends Activity {  

    // 聲明Button  

    private Button startBtn,stopBtn,bindBtn,unbindBtn;  

    @Override  

    public void onCreate(Bundle savedInstanceState) {  

        super.onCreate(savedInstanceState);  

        // 設定目前布局視圖  

        setContentView(R.layout.main);  

        // 執行個體化Button  

        startBtn = (Button)findViewById(R.id.startButton01);  

        stopBtn = (Button)findViewById(R.id.stopButton02);  

        bindBtn = (Button)findViewById(R.id.bindButton03);  

        unbindBtn = (Button)findViewById(R.id.unbindButton04);  

        // 添加監聽器  

        startBtn.setOnClickListener(startListener);  

        stopBtn.setOnClickListener(stopListener);  

        bindBtn.setOnClickListener(bindListener);  

        unbindBtn.setOnClickListener(unBindListener);  

    }  

    // 啟動Service監聽器  

    private OnClickListener startListener = new OnClickListener() {  

        @Override  

        public void onClick(View v) {  

            // 建立Intent  

            Intent intent = new Intent();  

            // 設定Action屬性  

            intent.setAction("com.amaker.ch07.app.action.MY_SERVICE");  

            // 啟動該Service  

            startService(intent);  

        }  

    };  

    // 停止Service監聽器  

    private OnClickListener stopListener = new OnClickListener() {  

            stopService(intent);  

   // 連接配接對象  

   private ServiceConnection conn = new ServiceConnection() {  

        public void onServiceConnected(ComponentName name, IBinder service) {  

            Log.i("SERVICE", "連接配接成功!");  

            Toast.makeText(MainActivity.this, "連接配接成功!", Toast.LENGTH_LONG).show();  

        public void onServiceDisconnected(ComponentName name) {  

            Log.i("SERVICE", "斷開連接配接!");  

            Toast.makeText(MainActivity.this, "斷開連接配接!", Toast.LENGTH_LONG).show();  

    // 綁定Service監聽器  

    private OnClickListener bindListener = new OnClickListener() {  

            // 綁定Service  

            bindService(intent, conn, Service.BIND_AUTO_CREATE);  

    // 解除綁定Service監聽器  

    private OnClickListener unBindListener = new OnClickListener() {  

            // 解除綁定Service  

            unbindService(conn);  

 /Chapter07_Service_Example/src/com/amaker/ch07/app/MyService.java

public class MyService extends Service{  

    // 可以傳回null,通常傳回一個有aidl定義的接口  

    public IBinder onBind(Intent intent) {  

        Log.i("SERVICE", "onBind..............");  

        Toast.makeText(MyService.this, "onBind..............", Toast.LENGTH_LONG).show();  

        return null;  

    // Service建立時調用  

    public void onCreate() {  

        Log.i("SERVICE", "onCreate..............");  

        Toast.makeText(MyService.this, "onCreate..............", Toast.LENGTH_LONG).show();  

    // 當用戶端調用startService()方法啟動Service時,該方法被調用  

    public void onStart(Intent intent, int startId) {  

        Log.i("SERVICE", "onStart..............");  

        Toast.makeText(MyService.this, "onStart..............", Toast.LENGTH_LONG).show();  

    // 當Service不再使用時調用  

    public void onDestroy() {  

        Log.i("SERVICE", "onDestroy..............");  

        Toast.makeText(MyService.this, "onDestroy..............", Toast.LENGTH_LONG).show();  

布局檔案

/Chapter07_Service_Example/res/layout/main.xml

&lt;?xml version="1.0" encoding="utf-8"?&gt;  

&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 

    android:orientation="vertical" 

    android:layout_width="fill_parent" 

    android:layout_height="fill_parent" 

    &gt;  

    &lt;Button   

        android:text="啟動Service"   

        android:id="@+id/startButton01"   

        android:layout_width="wrap_content"   

        android:layout_height="wrap_content"&gt;&lt;/Button&gt;  

        android:text="停止Service"   

        android:id="@+id/stopButton02"   

        android:text="綁定Service"   

        android:id="@+id/bindButton03"   

        android:text="解除綁定"   

        android:id="@+id/unbindButton04"   

&lt;/LinearLayout&gt; 

清單檔案

/Chapter07_Service_Example/AndroidManifest.xml

&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android" 

      package="com.amaker.ch07.app" 

      android:versionCode="1" 

      android:versionName="1.0"&gt;  

    &lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt;  

        &lt;activity android:name=".MainActivity" 

                  android:label="@string/app_name"&gt;  

            &lt;intent-filter&gt;  

                &lt;action android:name="android.intent.action.MAIN" /&gt;  

                &lt;category android:name="android.intent.category.LAUNCHER" /&gt;  

            &lt;/intent-filter&gt;  

        &lt;/activity&gt;  

        &lt;service android:name="MyService"&gt;  

                &lt;action android:name="com.amaker.ch07.app.action.MY_SERVICE"/&gt;  

        &lt;/service&gt;  

    &lt;/application&gt;  

    &lt;uses-sdk android:minSdkVersion="3" /&gt;  

&lt;/manifest&gt; 

執行個體二、遠端service調用

實作方式RPC(remote procedures call)遠端程序調用 (android interface definition)接口定義語言

/Chapter07_Service_Remote/src/com/amaker/ch07/app/MainActivity.java

import com.amaker.ch07.app.IPerson;  

import android.os.RemoteException;  

 *   

 * RPC 測試  

    // 聲明IPerson接口  

    private IPerson iPerson;  

    // 聲明 Button  

    private Button btn;  

    // 執行個體化ServiceConnection  

    private ServiceConnection conn = new ServiceConnection() {  

        @Override 

        synchronized public void onServiceConnected(ComponentName name, IBinder service) {  

            // 獲得IPerson接口  

            iPerson = IPerson.Stub.asInterface(service);  

            if (iPerson != null)  

                try {  

                    // RPC 方法調用  

                    iPerson.setName("hz.guo");  

                    iPerson.setAge(30);  

                    String msg = iPerson.display();  

                    // 顯示方法調用傳回值  

                    Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG)  

                            .show();  

                } catch (RemoteException e) {  

                    e.printStackTrace();  

                }  

    @Override 

        // 設定目前視圖布局  

        btn = (Button) findViewById(R.id.Button01);  

        //為Button添加單擊事件監聽器  

        btn.setOnClickListener(new OnClickListener() {  

            @Override 

            public void onClick(View v) {  

                // 執行個體化Intent  

                Intent intent = new Intent();  

                // 設定Intent Action 屬性  

                intent  

                        .setAction("com.amaker.ch09.app.action.MY_REMOTE_SERVICE");  

                // 綁定服務  

                bindService(intent, conn, Service.BIND_AUTO_CREATE);  

            }  

        });  

/Chapter07_Service_Remote/src/com/amaker/ch07/app/MyRemoteService.java

import com.amaker.ch07.app.IPerson.Stub;  

 * 使用Service将接口暴露給用戶端  

public class MyRemoteService extends Service{  

    private Stub iPerson = new IPersonImpl();  

        return iPerson;  

/Chapter07_Service_Remote/src/com/amaker/ch07/app/IPersonImpl.java

 * IPerson接口實作類  

public class IPersonImpl extends IPerson.Stub{  

    // 聲明兩個變量  

    private int age;  

    private String name;  

    // 顯示name和age  

    public String display() throws RemoteException {  

        return "name:"+name+";age="+age;  

    // 設定age  

    public void setAge(int age) throws RemoteException {  

        this.age = age;  

    // 設定name  

    public void setName(String name) throws RemoteException {  

        this.name = name;  

/Chapter07_Service_Remote/src/com/amaker/ch07/app/IPerson.aidl

interface IPerson {  

    void setAge(int age);  

    void setName(String name);  

    String display();  

/Chapter07_Service_Remote/res/layout/main.xml

&lt;?xml version="1.0" encoding="utf-8"?&gt; 

    &gt; 

        android:text="測試遠端Service"   

        android:id="@+id/Button01"   

        android:layout_height="wrap_content"&gt;&lt;/Button&gt; 

/Chapter07_Service_Remote/AndroidManifest.xml

      android:versionName="1.0"&gt; 

    &lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt; 

                  android:label="@string/app_name"&gt; 

            &lt;intent-filter&gt; 

                &lt;action android:name="android.intent.action.MAIN" /&gt; 

                &lt;category android:name="android.intent.category.LAUNCHER" /&gt; 

            &lt;/intent-filter&gt; 

        &lt;/activity&gt; 

        &lt;service android:name="MyRemoteService"&gt; 

                &lt;action android:name="com.amaker.ch07.app.action.MY_REMOTE_SERVICE"/&gt; 

        &lt;/service&gt; 

    &lt;/application&gt; 

    &lt;uses-sdk android:minSdkVersion="3" /&gt; 

本文轉自linzheng 51CTO部落格,原文連結:http://blog.51cto.com/linzheng/1080655

繼續閱讀