Android開發學習筆記:Service的簡介和啟動方式(轉)


轉自:http://liangruijun.blog.51cto.com/3061169/647804/

一.Service的簡介

1.Service 介紹和作用
Service是Android系統中的四大組件之一,它是一種長生命周期的,沒有可視化界面,運行於后台的一種服務程序。比如我們播放音樂的時候,有可能想邊聽音樂邊干些其他事情,當退出播放音樂的應用,如果不用Service,我 們就聽不到歌了,所以這時候就得用到Service了。
 
2. Service生命周期
Service的生命周期並不像Activity那么復雜,它只繼承了onCreate(),onStart(),onDestroy()三個方法,當第一次啟動Service時,先后調用了onCreate(),onStart()這兩個方法,當停止Service時,則執行onDestroy()方法,這里需要注意的是,如果Service已經啟動了,當我們再次啟動Service時,不會在執行onCreate()方法,而是直接執行onStart()方法。
 
二. Service的啟動方式
Service的有兩種啟動方式:Context.startService()和Context.bindService(),這兩種方式對Service生命周期的影響是不同的。
 
1.Context.startService()方式啟動
 
①Context.startService()方式的生命周期: 
啟動時,startService –> onCreate() –> onStart()
停止時,stopService –> onDestroy()
如果調用者直接退出而沒有停止Service,則Service 會一直在后台運行
 
Context.startService()方法啟動服務,在服務未被創建時,系統會先調用服務的onCreate()方法,接着調用onStart()方法。如果調用startService()方法前服務已經被創建,多次調用startService()方法並不會導致多次創建服務,但會導致多次調用onStart()方法。采用startService()方法啟動的服務,只能調用Context.stopService()方法結束服務,服務結束時會調用onDestroy()方法。
 
②Context.startService()方式啟動 Service的方法:
 
下面是具體例子:
 
MainActivity.java
package com.android.service.activity;  
 
import android.app.Activity;  
import android.content.Intent;  
import android.os.Bundle;  
import android.view.View;  
import android.view.View.OnClickListener;  
import android.widget.Button;  
 
public class MainActivity extends Activity  
{  
    private Button startBtn;  
    private Button stopBtn;  
    @Override 
    public void onCreate(Bundle savedInstanceState)  
    {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        startBtn = (Button) findViewById(R.id.startBtn);  
        stopBtn = (Button) findViewById(R.id.stopBtn);  
        //添加監聽器  
        startBtn.setOnClickListener(listener);  
        stopBtn.setOnClickListener(listener);  
    }  
      
    //啟動監聽器  
    private OnClickListener listener=new OnClickListener()  
    {         
        @Override 
        public void onClick(View v)  
        {  
            Intent intent=new Intent(MainActivity.this, ServiceDemo.class);  
            switch (v.getId())  
            {  
            case R.id.startBtn:  
                startService(intent);  
                break;  
            case R.id.stopBtn:  
                stopService(intent);  
                break;  
            default:  
                break;  
            }             
        }  
    };  
} 

ServiceDemo.java

package com.android.service.activity;  
 
import android.app.Service;  
import android.content.Intent;  
import android.os.IBinder;  
import android.util.Log;  
 
public class ServiceDemo extends Service  
{  
    private static final String TAG="Test";  
      
    @Override 
    //Service時被調用  
    public void onCreate()  
    {  
        Log.i(TAG, "Service onCreate--->");  
        super.onCreate();  
    }  
 
    @Override 
    //當調用者使用startService()方法啟動Service時,該方法被調用  
    public void onStart(Intent intent, int startId)  
    {  
        Log.i(TAG, "Service onStart--->");  
        super.onStart(intent, startId);  
    }  
 
    @Override 
    //當Service不在使用時調用  
    public void onDestroy()  
    {  
        Log.i(TAG, "Service onDestroy--->");  
        super.onDestroy();  
    }  
 
    @Override 
    //當使用startService()方法啟動Service時,方法體內只需寫return null  
    public IBinder onBind(Intent intent)  
    {  
        return null;  
    }  
}

main.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    > 
    <Button 
        android:id="@+id/startBtn" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:text="啟動 Service" 
        /> 
    <Button 
        android:id="@+id/stopBtn" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:text="停止 Service" 
        /> 
</LinearLayout> 

在AndroidManifest.xml文件中添加16~21行的聲明

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
      package="com.android.service.activity" 
      android:versionCode="1" 
      android:versionName="1.0"> 
    <uses-sdk android:minSdkVersion="10" /> 
 
    <application android:icon="@drawable/icon" android:label="@string/app_name"> 
        <activity android:name=".MainActivity" 
                  android:label="@string/app_name"> 
            <intent-filter> 
                <action android:name="android.intent.action.MAIN" /> 
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
        </activity> 
    <service android:name=".ServiceDemo" >    
             <intent-filter> 
                <action android:name="android.intent.action.MAIN" /> 
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
    </service>    
    </application> 
</manifest> 

當點擊啟動Service按鈕時,先后執行了Service中onCreate()->onStart()這兩個方法

當點擊 停止Service按鈕時,Service則執行了onDestroy()方法

2 .Context.bindService() 方式啟動:
 
①Context.bindService()方式的生命周期: 
綁定時,bindService -> onCreate() –> onBind()
調用者退出了,即解綁定時,Srevice就會unbindService –>onUnbind() –> onDestory()
 
用Context.bindService()方法啟動服務,在服務未被創建時,系統會先調用服務的onCreate()方法,接着調用onBind()方法。這個時候調用者和服務綁定在一起,調用者退出了,系統就會先調用服務的onUnbind()方法,接着調用onDestroy()方法。如果調用bindService()方法前服務已經被綁定,多次調用bindService()方法並不會導致多次創建服務及綁定(也就是說onCreate()和onBind()方法並不會被多次調用)。如果調用者希望與正在綁定的服務解除綁定,可以調用unbindService()方法,調用該方法也會導致系統調用服務的onUnbind()-->onDestroy()方法。
 
②Context.bindService()方式啟動 Service的方法:
綁定Service需要三個參數:bindService(intent, conn, Service.BIND_AUTO_CREATE);
第一個:Intent對象
第二個:ServiceConnection對象,創建該對象要實現它的onServiceConnected()和 onServiceDisconnected()來判斷連接成功或者是斷開連接
第三個:如何創建Service,一般指定綁定的時候自動創建

 下面是具體的例子:

MainActivity.java

package com.android.bindservice.activity;  
 
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;  
 
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.startBtn1);  
        stopBtn = (Button)findViewById(R.id.stopBtn2);  
        bindBtn = (Button)findViewById(R.id.bindBtn3);  
        unbindBtn = (Button)findViewById(R.id.unbindBtn4);  
          
        // 添加監聽器  
        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();  
            // 設置Class屬性  
            intent.setClass(MainActivity.this, BindService.class);  
            // 啟動該Service  
            startService(intent);  
        }  
    };  
      
    // 停止Service監聽器  
    private OnClickListener stopListener = new OnClickListener() {  
        @Override 
        public void onClick(View v) {  
            // 創建Intent  
            Intent intent = new Intent();  
            // 設置Class屬性  
            intent.setClass(MainActivity.this, BindService.class);  
            // 啟動該Service  
            stopService(intent);  
        }  
    };  
      
   // 連接對象  
   private ServiceConnection conn = new ServiceConnection() {  
        @Override 
        public void onServiceConnected(ComponentName name, IBinder service) {  
            Log.i("Service", "連接成功!");  
        }  
        @Override 
        public void onServiceDisconnected(ComponentName name) {  
            Log.i("Service", "斷開連接!");  
        }  
    };  
      
    // 綁定Service監聽器  
    private OnClickListener bindListener = new OnClickListener() {  
        @Override 
        public void onClick(View v) {  
            // 創建Intent  
            Intent intent = new Intent();  
            // 設置Class屬性  
            intent.setClass(MainActivity.this, BindService.class);  
           
            // 綁定Service  
            bindService(intent, conn, Service.BIND_AUTO_CREATE);  
        }  
    };  
          
    // 解除綁定Service監聽器  
    private OnClickListener unBindListener = new OnClickListener() {  
        @Override 
        public void onClick(View v) {  
            // 創建Intent  
            Intent intent = new Intent();  
            // 設置Class屬性  
            intent.setClass(MainActivity.this, BindService.class);  
            // 解除綁定Service  
            unbindService(conn);  
        }  
    };    
} 

BindService.java

package com.android.bindservice.activity;  
 
import android.app.Service;  
import android.content.Intent;  
import android.os.IBinder;  
import android.util.Log;  
 
public class BindService extends Service{  
      
    private static final String TAG="Test";  
      
    //返回null  
    public IBinder onBind(Intent intent) {  
        Log.i(TAG, "Service onBind--->");  
        return null;  
    }  
    // Service創建時調用  
    public void onCreate() {  
        Log.i(TAG, "Service onCreate--->");  
    }  
    // 當客戶端調用startService()方法啟動Service時,該方法被調用  
    public void onStart(Intent intent, int startId) {  
        Log.i(TAG, "Service onStart--->");  
    }  
    // 當Service不再使用時調用  
    public void onDestroy() {  
        Log.i(TAG, "Service onDestroy--->");  
    }  
    // 當解除綁定時調用  
    public boolean onUnbind(Intent intent) {    
        Log.i(TAG, "Service onUnbind--->");    
        return super.onUnbind(intent);    
    }    
}  
 

main.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    > 
    <Button   
        android:text="啟動Service"   
        android:id="@+id/startBtn1"   
        android:layout_width="match_parent"   
        android:layout_height="wrap_content" 
        />    
    <Button   
        android:text="停止Service"   
        android:id="@+id/stopBtn2"   
        android:layout_width="match_parent"   
        android:layout_height="wrap_content" 
        />    
    <Button   
        android:text="綁定Service"   
        android:id="@+id/bindBtn3"   
        android:layout_width="match_parent"   
        android:layout_height="wrap_content" 
        /> 
    <Button   
        android:text="解除綁定"   
        android:id="@+id/unbindBtn4"   
        android:layout_width="match_parent"   
        android:layout_height="wrap_content" 
        /> 
</LinearLayout> 

在AndroidManifest.xml文件中添加16~21行的聲明

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
      package="com.android.bindservice.activity" 
      android:versionCode="1" 
      android:versionName="1.0"> 
    <uses-sdk android:minSdkVersion="10" /> 
 
    <application android:icon="@drawable/icon" android:label="@string/app_name"> 
        <activity android:name=".MainActivity" 
                  android:label="@string/app_name"> 
            <intent-filter> 
                <action android:name="android.intent.action.MAIN" /> 
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
        </activity> 
        <service android:name=".BindService" >    
             <intent-filter> 
                <action android:name="android.intent.action.MAIN" /> 
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
    </service> 
    </application> 
</manifest> 

 


免責聲明!

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



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