Android四大組件之—— 使用服務進行後臺操作

這片文章對service總結的不錯,

什麼是服務

       服務是一個沒有可視化界面的組件,它可以在後臺長期運行並進行各種操作。

 

服務的創建

       我們只需要繼承Service類並實現相應的方法即可創建服務

       要想啓動服務,還得在AndroidManifest中註冊服務

 

服務類的示例代碼

package com.whathecode.servicedemo;
 
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
 
public class ExtendsionService extendsService
{
 
    /**
     * 當服務第一次被創建的時候調用此方法
     */
    @Override
    publicvoid onCreate()
    {
         
        super.onCreate();
        Toast.makeText(getBaseContext(),"服務被創建了", Toast.LENGTH_SHORT).show();
    }
     
    /**
     * 當通過startService方法啓動服務時此方法被調用
     */
    @Override
    publicint onStartCommand(Intent intent,int flags, int startId)
    {
        Toast.makeText(getBaseContext(),"服務被啓動了", Toast.LENGTH_SHORT).show();
        returnsuper.onStartCommand(intent, flags, startId);
    }
 
    @Override
    publicIBinder onBind(Intent intent)
    {
        returnnull;
    }
 
    @Override
    publicvoid onDestroy()
    {
        super.onDestroy();
    }
 
}

使用startService啓動服務

主界面的邏輯代碼:

 

package com.whathecode.servicedemo;
 
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
 
public class MainActivity extendsActivity
{
 
    Intent service =null;
    @Override
    protectedvoid onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         
        //創建服務
        service =new Intent(this, ExtendsionService.class);
    }
 
    publicvoid start(View view)
    {
        //啓動服務
        startService(service);
    }
     
    publicvoid stop(View view)
    {
        //停止服務
        stopService(service);
    }
}

註冊服務:

 

1
<serviceandroid:name="com.whathecode.servicedemo.BackgroundService"></service>

 

運行效果:

 

startService

 

注意:

         當我們第一次點擊啓動服務按鈕的時候,onCreate方法和onStartCommand方法依次執行,

         但在第二次點擊啓動服務按鈕的時候,這個服務已經處於運行狀態,onCreate方法不再執行第二次,

         而onStartCommand方法總是在調用startService啓動服務的時候執行。

         onDestroy方法在stopService方法被調用後執行。

 

除了使用startService方法啓動服務外,我們還可以使用Bind的方式啓動服務。

前者和後者的不同在於:

      服務的生命週期不依賴於啓動者。服務被啓動後一直在後臺運行直到調用stopService被停止。

       使用Bind方式啓動服務,服務的生命週期依賴於啓動者。即服務在啓動者退出後自動銷燬。

 

使用Bind方式啓動服務

主要使用bindService方法啓動服務,unbindService方法銷燬服務。

使用此方式啓動服務的好處是,bind定成功的時候服務返回一個IBinder對象,

我們可以通過在服務類裏面實現這個對象,從而訪問服務裏面的具體方法。

從而達到和服務溝通的目的。

 

注意:

        我們不能以直接實例化服務的方式調用裏面的方法。

 

另外:

       如果在退出服務的時候沒有解綁,那麼程序就會拋出異常IllegalArgumentException異常。

       因此,每次調用bindService啓動服務,完成後需要退出服務都需要使用unbindService 解綁。  

 

示例代碼:


package com.whathecode.servicedemo;
 
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.view.View;
 
public class MainActivity extendsActivity
{
 
    Intent service =null;
    IReceptionist rpst;
 
    /**
     * bindService和unbindService方法使用的參數
     */
    privateServiceConnection conn = newServiceConnection()
    {
         
        //此方法在服務連接被意外終止的時候被調用,
        @Override
        publicvoid onServiceDisconnected(ComponentName name)
        {
         
        }
         
        //當服務被連接上的時候自動調用這個方法,第二個參數是服務類onBind方法中返回的對象
        @Override
        publicvoid onServiceConnected(ComponentName name, IBinder service)
        {
            rpst = (IReceptionist) service;
            rpst.callExtendsionNumber();
        }
    };
     
    @Override
    protectedvoid onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         
        //創建服務
        service =new Intent(this, ExtendsionService.class);
    }
 
    publicvoid start(View view)
    {
        //啓動服務
        startService(service);
    }
     
    publicvoid stop(View view)
    {
        //停止服務
        stopService(service);
    }
     
    publicvoid bind(View view)
    {
        //綁定服務
        bindService(service, conn , BIND_AUTO_CREATE);
    }
     
    publicvoid unBind(View view)
    {
        //解綁服務
        unbindService(conn);
    }
}

繼承ServiceBinder對象,並實現自定義接口:

通過這個方式,我們可以暴露只需要的方法,實現代碼的保護。

 

IReceptionist接口代碼:
package com.whathecode.servicedemo;
 
public interface IReceptionist
{
    publicvoid callExtendsionNumber();
}


 

ExtendsionService服務類代碼:

 

package com.whathecode.servicedemo;
 
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
 
public class ExtendsionService extendsService
{
 
    privatestatic final String TAG = "ExtendsionService";
 
    /**
     * 當服務第一次被創建的時候調用此方法
     */
    @Override
    publicvoid onCreate()
    {
         
        super.onCreate();
        Toast.makeText(getBaseContext(),"服務被創建了", Toast.LENGTH_SHORT).show();
    }
     
    /**
     * 當通過startService方法啓動服務時此方法被調用
     */
    @Override
    publicint onStartCommand(Intent intent,int flags, int startId)
    {
        Toast.makeText(getBaseContext(),"服務被啓動了", Toast.LENGTH_SHORT).show();
        returnsuper.onStartCommand(intent, flags, startId);
    }
 
    @Override
    publicIBinder onBind(Intent intent)
    {
        returnnew ServiceBinder();
    }
 
    @Override
    publicvoid onDestroy()
    {
        Toast.makeText(getBaseContext(),"服務被銷燬了", Toast.LENGTH_SHORT).show();
        Log.d(TAG,"服務被銷燬了");
        super.onDestroy();
    }
     
    publicvoid putExtendsion()
    {
        Toast.makeText(getBaseContext(),"正在幫你轉接分機", Toast.LENGTH_SHORT).show();
    }
     
    /**
     *
     * 繼承Binder並實現IReceptionist接口
     * 繼承Binder類的目的是onBind方法中需要返回這個類型的對象
     *
     * 實現IReceptionist接口是暴露方法的需要
     */
    privateclass ServiceBinder extends Binder implements IReceptionist
    {
        publicvoid callExtendsionNumber()
        {
            putExtendsion();
        }
         
        privatevoid otherMethod()
        {
             
        }
    }
}


 

運行效果:

bindService

 

注意看上圖,我們在按下返回鍵的時候,Activity被銷燬,由它啓動的服務也跟着被銷燬。

這樣的服務貌似作用不大,有沒有辦法在退出Activity的時候不退出服務呢?

答案是有的:Android允許我們先啓動一個服務,然後再調用bindService綁定到服務,

                    這樣,我們既可以達到和服務溝通的目的,也可以使服務長期在後臺運行。

 

看下圖:

bindService

 

通過下面的圖,就可以更清楚地理解上面代碼的工作原理:

 

Service


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章