Android 組件之Service解析

來源:互聯網
上載者:User

標籤:pat   建立   四大組件   string   false   anr   解決問題   span   ace   

原創文章,轉載請註明 http://blog.csdn.net/leejizhou/article/details/50866875 李濟洲的部落格

Service是Android四大組件之中的一個。Service主要作用於後台,能夠進行一些背景操作,它沒實使用者介面。它跟Activity比較類似,某種意義上能夠理解為“Service是沒實使用者介面的Activity“,那麼我們什麼時候須要使用Service呢?比如:音樂App現正播放音樂我們想切換到閱讀App又不想讓音樂停止就會用到Service,音樂App正在下載音樂我們切換到案頭又不想讓下載停止就會使用到Service。

編寫Activity須要兩步:1:編寫Activity的子類 2:在AndroidManifest.xml中配置此Activity,相同編寫Service也須要兩步:

1:定義一個繼承自Service的子類
2:在AndroidManifest.xml中配置此Service

startService

我們先編寫一個簡單的StartService示範範例程式來示範怎樣實現Android後台操作
先定義一個Service的子類,然後複寫一些生命週期函數

/** * Blog:http://blog.csdn.net/leejizhou * 李濟洲的部落格 */public class MyService extends Service {    //Service中唯一的抽象方法。必須在子類中實現,用來和Activity通訊。先返回NULL    @Nullable    @Override    public IBinder onBind(Intent intent) {        return null;    }    //複寫Service的一些生命週期函數    //onCreate會在Service第一次建立的時候調用    @Override    public void onCreate() {        super.onCreate();        Log.d("MyService","----onCreate executed----");    }    //onStartCommand會在Service每次啟動的時候調用    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        Log.d("MyService","----onStartCommand----");        return super.onStartCommand(intent, flags, startId);    }    //onDestroy會在Service銷毀時候調用    @Override    public void onDestroy() {        super.onDestroy();        Log.d("MyService", "----onDestroy----");    }}

以下是Service的生命週期,為什麼有兩種呢?由於啟動Servcie有兩種方式第一個是startService()主要用於啟動一個Service運行背景工作不進行通訊,還有一個是bindService()是啟動一個跟組件綁定的Service能夠進行通訊,先介紹的是startService()。

然後在AndroidManifest.xml中進行配置此Service。千萬不要忘記。

  <service android:name=".MyService"></service>

定義好Service後,接下來就是啟動和停止這個服務了。啟動和停止主要靠Intent來實現,這裡我定義了兩個Button用來啟動和停止。部分代碼略(文章結尾會提供原始碼),主要看下啟動和停止Service的實現代碼。

 //開啟Service        findViewById(R.id.StartService).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent=new Intent(MainActivity.this,MyService.class);                startService(intent);            }        }); //停止Service        findViewById(R.id.StopService).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent=new Intent(MainActivity.this,MyService.class);                stopService(intent);            }        });

點擊開啟Service能夠看到OnCreate和OnStartCommand被運行了,一個簡單的後台Service就被啟動了

然後點擊停止。能夠看到OnDestroy被運行了

這裡可能你會問了。啟動Service,OnCreate和OnStartCommand都被運行了,他倆有什麼差別呢?onCreate會在Service第一次建立的時候調用,假設一個Service沒有Stop再次啟動這個Service的話是不會再調用onCreate方法了,可是每次OnStartCommand都會被調用。所以後台須要啟動並執行代碼邏輯我們一般須要放到OnStartCommand方法裡面。

Ok 在Activity裡面啟動一個簡單的Service後台服務就完畢了,可是你要知道的是通過startService()啟動這個服務後就和Activity就沒有關係了,即使你這個Activity被銷毀這個Service依舊會在後台運行。切記通過startService()啟動服務任務結束後在Activity中調用 stopService()結束掉這個Service。或者在Servcie子類中調用stopSelf()來結束自己。

上面介紹了startService啟動服務,它能夠很簡單的啟動後台Service進行一些邏輯操作,可是無法進行控制和通訊,以下介紹下BindService能夠解決問題。

bindService

以下實現一個後台Service進行數值的遞增運算。Activity能夠即時查看Service此時的數值的小示範範例來瞭解bindService的使用。

定義Service。這裡我們要實現onBind的方法。在這裡onStartCommand無需複寫,由於通過bindService啟動服務是不回調此方法的。Service的onCreate裡面進行的了一個迴圈的數值運算。

/** * Blog:http://blog.csdn.net/leejizhou * 李濟洲的部落格 */public class MyService extends Service {    //當前數值    private int num=0;    //是否停止迴圈    private boolean isgo=true;    //BindService 須要實現onBind方法 自己定義一個Binder對象返回    private MyBinder binder=new MyBinder();    @Nullable    @Override    public IBinder onBind(Intent intent) {        return binder;    }    public class MyBinder extends Binder{         //建立一個方法用於返回當前數值         public int getNum(){             return num;         }     }    //Service建立時候回調此方法 這裡定義一個迴圈 不斷更改num的值    @Override    public void onCreate() {        super.onCreate();        //進行迴圈操作,每秒數值加1       new Thread(new Runnable() {           @Override           public void run() {               while(isgo){                   try {                       Thread.sleep(1000);                   } catch (InterruptedException e) {                       e.printStackTrace();                   }                   num++;                   Log.i("MyService",num+"");               }           }       }).start();    }    //這裡不須要複寫此方法。由於bindService啟動服務不會調用此方法//    @Override//    public int onStartCommand(Intent intent, int flags, int startId) {//        return super.onStartCommand(intent, flags, startId);//    }    //Service斷開時回調此方法    @Override    public boolean onUnbind(Intent intent) {        Log.i("MyService","----onUnbind----");        return super.onUnbind(intent);    }    //Service銷毀是回調此方法    @Override    public void onDestroy() {        super.onDestroy();        isgo=false;        Log.i("MyService","----onDestroy----");    }}

然後再AndroidManifest.xml中佈建服務,一定一定一定不要忘記。

 <service android:name=".MyService"></service>

之後在Activity裡面通過bindService啟動服務,Activity裡面三個button用來啟動 停止 和擷取數值

/** * Blog:http://blog.csdn.net/leejizhou * 李濟洲的部落格 */public class MainActivity extends AppCompatActivity {    //擷取Service中的Binder對象    MyService.MyBinder binder;    //定義一個ServiceConnection對象    private ServiceConnection connection=new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            //Activity與Service串連成功時候回調此方法            binder=(MyService.MyBinder)service;        }        @Override        public void onServiceDisconnected(ComponentName name) {            //Activity與Service中斷連線時回調此方法,Activity主動調用unBindService將不掉用此方法。僅僅在異常終止時刻調用            Log.i("MyService","----onServiceDisconnected-----");        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //啟動Service        findViewById(R.id.bindService).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent bindIntent=new Intent(MainActivity.this, MyService.class);                //這裡第一個參數傳入intent 第二個參數傳入ServiceConnection對象                //第三個參數指Activity和Service綁定時是否建立服務。這裡直接傳BIND_AUTO_CREATE就好了。之後Service的onCreate會得到運行                bindService(bindIntent,connection, Service.BIND_AUTO_CREATE);            }        });        //停止Service        findViewById(R.id.UnBindService).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //解除綁定Service               unbindService(connection);            }        });        //擷取Service中此刻的數值        findViewById(R.id.getnum).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Toast.makeText(MainActivity.this,"Service的數值"+binder.getNum()+"",3000).show();            }        });    }}

bindService運行生命週期

注意到Activity中ServiceConnection對象中的OnServiceConnected方法中有一個IBinder對象,該對象就可以實現Activity與Service之間的通訊,使用bindService方式啟動Service的時候,Service子類必須實現onBind方法,onBind方法返回的IBinder對象將會傳遞到onServiceConnected(ComponentName name, IBinder service)其中來實現通訊互動。

這樣Activity和Service通訊的小示範範例就完畢了,值得注意的是通過onBind方法啟動Service,Service和Activity是綁定狀態的。那麼假設Activity被銷毀Service也會跟著一起銷毀這點要注意,要區分startService和bindService的差別。

那麼你可能會問假設我想讓Service能夠和Activity通訊同一時候又能夠不隨Activity銷毀該怎樣做呢?僅僅須要 startService和bindService一起調用就能夠了。假設同一時候調用了start和bind,那麼調用unbindService將不會停止Service,而必須調用 stopService 或 Service的 stopSelf 來停止服務。

在使用Service中有一個誤區會有人以為在Service中的onCreate中能夠進行耗時操作。這是不正確的,Service依舊是運行在主線程中的,假設直接進行耗時操作很easy造成ANR,所以即使在Service中耗時操作依舊要放到子線程其中。

最後總結下什麼情況下使用startService或bindService呢。假設你僅僅想啟動一個後台服務去運行一個某項長期任務的話使用startService就能夠了。假設你想要與正在啟動並執行後台Service取得聯絡的話能夠使用bindService,假設想要Service長期運行不隨Activity銷毀而且能夠進行通訊那麼就調用了startService後再調用bindService。Service的總結先告一段落。有什麼問題能夠在下方留言,感謝。

本篇原始碼 http://download.csdn.net/detail/leejizhou/9459862

Android 組件之Service解析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.