Android開發歷程_13(Service的使用)


 

  Service在android中的地位和activity,只是它沒有單獨的界面,一般都是在后台運行,主要是用來運行一些消耗時間比較長的任務。我們可以用它來發送intent來更新activity的UI。另外需要注意的是service既不是一個單獨的進程,也不是一個單獨的線程,它與activity一起在同一個進程中。

  關於android的sevice,網上這篇文章對service做了比較詳細的介紹,並通過啟動音樂播放器的例子來講解service:http://www.cnblogs.com/allin/archive/2010/05/15/1736458.html

 

  Service的生命周期

  既然service和activity一樣重要,則和activity類似,它也有自己的生命周期。它的生命周期與啟動service的方式不同與不同,比如在activity中啟動service時,如果采用的是         activity.startService()啟動,則該service的生命周期一般為:

  onCreate()->onStart()/onStartCommand()->service running->onDestroy().

  如果是activity.bindService()啟動,則該service的生命周期為:

  onCreate()->onBind()->service running->onUnbind()->onDestrop().

 

  實驗部分

  本次實驗主要是學習怎樣在activity中啟動一個service,啟動的service的生命周期順序是哪些,然后service通過廣播機制向特定的activity傳遞數據,傳送數據當然用的是intent,然后接收到該廣播的activity讀取intent中的數據,根據讀取到的數據來更新activity的UI。

  關於怎樣通過service廣播機制來更新activity的UI,可以閱讀網上的這篇文章:http://www.pocketdigi.com/20110303/197.html

  需要注意的是service類是繼承的android框架中的Service類,程序中需要將寫好的service在AndriodManiFest.xml中進行注冊,注冊方法和activity的注冊類似。

  本程序的activity中有2個按鈕和1個TextView,2個按鈕分別用來啟動service和停止service,然后在activtiy和service的生命周期函數中各自在后台打印出相關語句,同時為了方便觀察,程序也直接將相關語句輸出到了textview中。

 

  啟動程序后,界面如下:

  

 

  單擊一次start service按鈕,然后單擊一次end service,再單擊一次start service按鈕后,界面輸出如下:

  

 

  后台輸出如下:

  

 

 

程序主要部分代碼和注釋(附錄有實驗工程code下載鏈接):

MainActivity.java:

package com.example.service;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;



public class MainActivity extends Activity {

    private  TextView text = null;
    private  Button start = null;
    private  Button end = null;
    MyReceiver receiver;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        text = (TextView)findViewById(R.id.text);
        start = (Button)findViewById(R.id.start);
        start.setOnClickListener(new StartOnClickListener());
        end = (Button)findViewById(R.id.end);
        end.setOnClickListener(new EndOnClickListener());
        
        System.out.println("Activity onCreate");
        text.append("\nActivity onCreate...");
        
        //因為該activity要接收廣播消息,所以先頂一個一個接收器對象
        //該對象自己實現,是繼承BroadcastReceiver的
        receiver=new MyReceiver();
        //定義一個IntentFilter的對象,來過濾掉一些intent
        IntentFilter filter = new IntentFilter();
        //只接收發送到action為"android.intent.action.MAIN"的intent
        //"android.intent.action.MAIN"是在MainFest中定義的
        filter.addAction("android.intent.action.MAIN");
        //啟動廣播接收器
        MainActivity.this.registerReceiver(receiver, filter);
        
    }
    
    public class MyReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            
            Bundle bundle = intent.getExtras();
            if(bundle.getInt("i") == 1)
                text.append("\nService onBind...");
            else if(bundle.getInt("i") == 2)
                text.append("\nService onCreate...");
            else if(bundle.getInt("i") == 3)
                text.append("\nService onStartCommand...");
            else if(bundle.getInt("i") == 4)
                text.append("\nService onDestroy...");
    
        }       
    }

    private class StartOnClickListener implements OnClickListener
    {
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Intent intent = new Intent();
            //跳轉到service用startService,以前跳轉到activity用的是startactivity
            intent.setClass(MainActivity.this, FisrtService.class);
            //啟動service
            startService(intent);
        }       
    }
    
    private class EndOnClickListener implements OnClickListener
    {
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Intent intent = new Intent();
            intent.setClass(MainActivity.this, FisrtService.class);
            //結束service
            stopService(intent);
        }       
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

 

FirstService.java:

package com.example.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;


//從Service類繼承而來
public class FisrtService extends Service{

    Intent intent = new Intent();
    //intent.setAction("android.intent.action.MAIN");
    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        System.out.println("Service onBind");
        intent.putExtra("i", 1);
        //service設置需要接收廣播intent的activity
        intent.setAction("android.intent.action.MAIN");
        //service通過廣播發送intent
        sendBroadcast(intent);
        return null;
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        System.out.println("Service onCreate");
        intent.putExtra("i", 2);
        intent.setAction("android.intent.action.MAIN");
        sendBroadcast(intent);
        
    }

    //onStartCommand與onStart類似,多了一個參數而已
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub
        System.out.println("flags---->"+flags);
        System.out.println("startId---->"+startId);
        System.out.println("Service onStartCommand");
        
        //不懂為什么這里要重新開一個intent,它的activity才能接收到它
        Intent intent1 = new Intent();
        intent1.putExtra("i", 3);
        intent1.setAction("android.intent.action.MAIN");
        sendBroadcast(intent1);
        
//        //很奇怪為什么這里這樣用,在activity中竟然接收不到該intent,一定要重新開一個intent?
//        intent.putExtra("i", 3);
//        intent.setAction("android.intent.action.MAIN");
//        sendBroadcast(intent);
        
        return super.onStartCommand(intent, flags, startId);
    }
    
    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        System.out.println("Service onDestroy");
        intent.putExtra("i", 4);
        intent.setAction("android.intent.action.MAIN");
        sendBroadcast(intent);
    }

}

 

Activity_main.xml:

<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" >

    <TextView
        android:id="@+id/text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello_service"
        android:layout_alignParentTop="true"
        />
    <Button
        android:id="@+id/end"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="@string/end"
        />
    <Button
        android:id="@+id/start"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        
          android:layout_above="@id/end"
        android:text="@string/start"
        />

</RelativeLayout>

 

 AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.service"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".FisrtService"></service>
    </application>

</manifest>

 

 

  總結:使用service可以在主界面運行的時候也能在后台運行多個服務,並且結合廣播機制可以完成一些常見的功能。

 

  附錄:

  實驗工程code下載

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM