6 四大组件之Service
6-1?Servie概述
組件篇——Service
定義:
1.后臺(tái)運(yùn)行,不可見(jiàn),沒(méi)有界面
2.優(yōu)先級(jí)高于Activity
Service是Android系統(tǒng)的后臺(tái)服務(wù)組件,適用于開發(fā)無(wú)界面、長(zhǎng)時(shí)間運(yùn)行的應(yīng)用功能。
Service特點(diǎn)如下:
沒(méi)有用戶界面
不會(huì)輕易被Android系統(tǒng)終止
在系統(tǒng)資源恢復(fù)后Service也將自動(dòng)恢復(fù)
運(yùn)行狀態(tài)
可用于進(jìn)程間通信
用途:
播放音樂(lè),記錄地理信息位置的改變,監(jiān)聽(tīng)某種動(dòng)作
注意:
-運(yùn)行在主線程,不能用它來(lái)做耗時(shí)的請(qǐng)求或者動(dòng)作
-可以在服務(wù)中開一個(gè)線程,在線程中做耗時(shí)操作
類型:
本地服務(wù)(Local Service):
應(yīng)用程序內(nèi)部
start方式:startService stopService stopSelf stopSelfResult
啟動(dòng)方式使用Service
通過(guò)調(diào)用Context.startService()啟動(dòng)Service,通過(guò)調(diào)用Context.stopService()或Service.stopSefl()停止Service
Bind方式:bindService unbindService
綁定方式使用Service
使用Service的組件通過(guò)Context.bindService()建立服務(wù)鏈接,通過(guò)Context.unbindService()停止服務(wù)鏈接
如果在綁定過(guò)程中Service沒(méi)有啟動(dòng),Context.bindService()會(huì)自動(dòng)啟動(dòng)Service
遠(yuǎn)程服務(wù)(Remote Service):
Android系統(tǒng)內(nèi)部的應(yīng)用程序間之間
定義IBinder接口
生命周期:
通過(guò)startService()方法啟動(dòng)的服務(wù)于調(diào)用者沒(méi)有關(guān)系,即使調(diào)用者關(guān)閉了,服務(wù)仍然運(yùn)行想停止服務(wù)要調(diào)用Context.stopService(),此時(shí)系統(tǒng)會(huì)調(diào)用onDestory(),使用此方法啟動(dòng)時(shí),服務(wù)首次啟動(dòng)系統(tǒng)先調(diào)用服務(wù)的onCreate()-->onStart(),如果服務(wù)已經(jīng)啟動(dòng)再次調(diào)用只會(huì)觸發(fā)onStart()方法
onCreate():Service的生命周期開始,完成Service的初始化工作;
onStart():活動(dòng)生命周期開始;
onDestroy():Service的生命周期結(jié)束,釋放Service所有占用的資源;
使用bindService()啟動(dòng)的服務(wù)與調(diào)用者綁定,只要調(diào)用者關(guān)閉服務(wù)就終止,使用此方法啟動(dòng)時(shí),服務(wù)首次啟動(dòng)系統(tǒng)先調(diào)用服務(wù)的onCreate()-->onBind(),如果服務(wù)已經(jīng)啟動(dòng)再次調(diào)用不會(huì)再觸發(fā)這2個(gè)方法,調(diào)用者退出時(shí)系統(tǒng)會(huì)調(diào)用服務(wù)的onUnbind()-->onDestory(),想主動(dòng)解除綁定可使用Contex.unbindService(),系統(tǒng)依次調(diào)用onUnbind()-->onDestory();
bindService()綁定Servcie, onCreate()和onBindle()將先后被調(diào)用。
unbindService()取消綁定Servcie,onUnbind()將被調(diào)用,如果onUnbind()返回true,則表示在調(diào)用者綁定新服務(wù)時(shí),onRebind()函數(shù)將被調(diào)用
非綁定式的service的生命周期
startService()--->onCreate()--->onStartCommand()--->ServingRunning--->onStop()--->onDestory()服務(wù)停止
綁定式的service的生命周期
bindService()--->onCreate()--->onBind()--->用戶與服務(wù)綁定?在解綁服務(wù)?onUnbind()--->onDestory()服務(wù)停止
start方式特點(diǎn):
-服務(wù)跟啟動(dòng)源沒(méi)有任何聯(lián)系?
-無(wú)法得到服務(wù)對(duì)象
Bind方式特點(diǎn):
-通過(guò)Ibinder接口實(shí)例,返回一個(gè)ServerConnnection對(duì)象給啟動(dòng)源
-通過(guò)ServiceConnection對(duì)象的相關(guān)方法可以得到Service對(duì)象
?
6-2?Start啟動(dòng)
start方式的啟動(dòng)時(shí):
第一次創(chuàng)建Service需要調(diào)用onCreate(),而后調(diào)用onStartCommand(),不管調(diào)用了多少次的onStartCOmmand(),停止的時(shí)候只調(diào)用一次onDestroy();
StartService
1.?使用方法:
(1)寫一個(gè)MyStartService繼承自Service,重寫它的各種方法onCreate()、onStartCommand()、onDestory()
(2)在AndroidManifest.xml中注冊(cè)這個(gè)Service
(3)在主線程Activity中通過(guò)startSerice(intent)方式啟動(dòng)
(4)通過(guò)stopService(intent)方式停止
2.?關(guān)于StartService
(1)啟動(dòng)方式是通過(guò)啟動(dòng)intent方式實(shí)現(xiàn)
(2)啟動(dòng)之后該Service和啟動(dòng)源沒(méi)有關(guān)系,即使主線程退出了,service還會(huì)繼續(xù)運(yùn)行
由于Service和Activity類似,屬于Android四大組件之一,所以我們需要在AndroidManifest.xml中進(jìn)行注冊(cè)。我們的組件都需要在AndroidManifest.xml中進(jìn)行注冊(cè)。
3.啟動(dòng)Service
顯式啟動(dòng)
Intent中指明Service所在的類,并調(diào)用startService(Intent)函數(shù)啟動(dòng)Service
final Intent serviceIntent = new Intent(this,RandomService.class);startService(serviceIntent);隱式啟動(dòng)
需要隱式開啟Service,則可以在注冊(cè)Service時(shí),聲明Intent-filter的action屬性
<service android:name=".RandomService" ><intent-filter><action android:name="StartRandomService" /></intent-filter> </service> final Intent serviceIntent = new Intent(); serviceIntent.setAction("edu.hrbeu.RandomService");?
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Start:" /><Buttonandroid:id="@+id/start"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="StartService" /><Buttonandroid:id="@+id/stop"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="StopService" /><TextViewandroid:id="@+id/textView2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Bind:" /><Buttonandroid:id="@+id/bind"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="BindService" /><Buttonandroid:id="@+id/play"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="播放" /><Buttonandroid:id="@+id/pause"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="暫停" /><Buttonandroid:id="@+id/next"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="下一首" /><Buttonandroid:id="@+id/pervious"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="上一首" /><Buttonandroid:id="@+id/unbind"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="doClick"android:text="UnBindService" /></LinearLayout>MainActivity.java
package com.example.test;import android.app.Activity; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.view.View;public class MainActivity extends Activity {Intent intent1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void doClick(View v) {switch (v.getId()) {case R.id.start:intent1 = new Intent(MainActivity.this, MyStartService.class);startService(intent1);break;case R.id.stop:stopService(intent1);break;}} }MyStartService.java
package com.example.test;import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log;public class MyStartService extends Service {@Overridepublic void onCreate() {// TODO Auto-generated method stubLog.i("info", "Service--onCreate()");super.onCreate();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// TODO Auto-generated method stubLog.i("info", "Service--onStartCommand()");return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {// TODO Auto-generated method stubLog.i("info", "Service--onDestroy()");super.onDestroy();}@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubLog.i("info", "Service--onBind()");return null;}}AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.test"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="15"android:targetSdkVersion="15" /><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid: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="com.example.servicedemo.MyStartService"></service></application></manifest>?
6-3?Bind啟動(dòng)
1.通過(guò)綁定服務(wù)獲取回傳數(shù)據(jù):
通過(guò)Ibinder接口實(shí)例(繼承的類里面返回一個(gè)Ibinder對(duì)象的抽象方法),返回一個(gè)serviceConnection對(duì)象給啟動(dòng)源,因?yàn)镮binder里面含有我們要的數(shù)據(jù),這里可以定義個(gè)內(nèi)部類繼承Binder里面做想返回的參數(shù)
?
2.使用onBind()方法的IBinder返回值給啟動(dòng)源返回信息?但是IBinder不能直接使用?需要通過(guò)Ibinder接口實(shí)例?返回一個(gè)ServiceConnection對(duì)象給啟動(dòng)源,通過(guò)ServiceConnection對(duì)象的相關(guān)方法可以得到Service,MyBinder是繼承自Binder類的,而Binder類實(shí)際上實(shí)現(xiàn)了IBinder接口。
public class MyBinder extends Binder{public MyBindServic getService(){return MyBindService.this;//返回這個(gè)Service的實(shí)例} } public IBunder onBind(Intent intent){return new MyBinder(); }?
3.在啟動(dòng)源定義ServiceConnection?該對(duì)象在綁定服務(wù)時(shí)傳輸?shù)椒?wù)端(bindService(intent,conn,Service.BIND_AUTO_CREATE))?綁定后?通過(guò)onServiceConnected()?方法獲取service對(duì)象
?
4.unbindservice執(zhí)行后,不能重復(fù)調(diào)用,會(huì)報(bào)錯(cuò),并且在destroy的時(shí)候必須解綁,?stopserveice則不會(huì),
?
5.服務(wù)的兩種啟動(dòng)方式:
1).通過(guò)startService(Intent?intent)啟動(dòng),stopService(Intent?intent)停止,比較簡(jiǎn)單。服務(wù)啟動(dòng)后與啟動(dòng)源無(wú)關(guān),也無(wú)返回服務(wù)本身。需注意要在配置文件中注冊(cè)服務(wù)。
2).通過(guò)bindService(Intent?intent,ServiceConnection?conn,int?flags)綁定服務(wù)啟動(dòng),unbindService(ServiceConnection?conn)去綁定停止,該方式可以返回服務(wù)本身,與啟動(dòng)源相關(guān)。
?
6.通過(guò)bindService綁定服務(wù)啟動(dòng)的具體步驟:
1)Intent?intent?=?new?Intent(上下文,?目標(biāo)服務(wù)名.class);
bindService(intent,?conn,?Service.BIND_AUTO_CREATE);//綁定
2)在自定義的服務(wù)類中通過(guò)自定義一個(gè)內(nèi)部類:
public?class?MyBinder?extends?Binder?{
public?MyBindService?getService()?{
return?MyBindService.this;//?獲取服務(wù)
}
}來(lái)返回服務(wù)本身
同時(shí)在自定義服務(wù)類重新父類Service的方法:
public?IBinder?onBind(Intent?intent)?{
//?TODO?Auto-generated?method?stub
return?new?MyBinder();
}
該方法可返回服務(wù)本身.
3)在啟動(dòng)源的Activity中創(chuàng)建一個(gè)ServiceConnection實(shí)例,初始化ServiceConnection接口,在接口方法中重寫方法
ServiceConnection?conn?=?new?ServiceConnection()?{
//當(dāng)啟動(dòng)源跟service的連接意外丟失的時(shí)候會(huì)調(diào)用
//比如service崩潰了,或被強(qiáng)行殺死了
public?void?onServiceDisconnected(ComponentName?name)?{
}
//當(dāng)啟動(dòng)源跟service成功連接之后會(huì)調(diào)用這個(gè)方法
public?void?onServiceConnected(ComponentName?name,?IBinder?service)?{
myBindService?=?((MyBinder)service).getService();//大類轉(zhuǎn)化為自身的小類,獲取內(nèi)部類中的方法,從而獲得服務(wù)本身
}};
4)bindService()中指定ServiceConnection?conn參數(shù)
bindService(intent2,?conn,?Service.BIND_AUTO_CREATE);
5)在自定義的繼承于Servic類的類中,添加需要的方法,在啟動(dòng)Service的Activity中可以直接調(diào)用服務(wù)中的方法。
通過(guò)bindService()啟動(dòng)的服務(wù)是和啟動(dòng)源(Activity)綁定在一起的,如果Activity退出的時(shí)候沒(méi)有調(diào)用unbindService()進(jìn)行解綁定(停止),那么程序會(huì)報(bào)錯(cuò)。所以我們需要在Activity的onDestroy()方法中調(diào)用unbindService()進(jìn)行解綁定。而且對(duì)于已經(jīng)解綁定的服務(wù)再次進(jìn)行解綁定,那么也會(huì)報(bào)錯(cuò),這點(diǎn)和通過(guò)startService啟動(dòng)的服務(wù)不同,stopService()方法可以調(diào)用多次。
?
7.StartService和BindService
1).?StartService啟動(dòng)后啟動(dòng)源和Service沒(méi)有關(guān)系,BindService調(diào)用bindService()啟動(dòng)service后啟動(dòng)源和Service相關(guān),在退出activity之前必須要調(diào)用unbindService()取消綁定。
2).?startService()和bindService()可以混合使用。如果我們想要Activity退出了,但是服務(wù)還在繼續(xù),那么我們就要選用startService的方式來(lái)啟動(dòng)服務(wù),如果我們想要在Activity中獲取Service對(duì)象,那么我們需要用bindService方法結(jié)合ServiceConnection來(lái)啟動(dòng)Service,但是這種方法,由于將Service和Activity綁定在了一起,所以當(dāng)Activity退出的時(shí)候,我們需要unbindService()來(lái)停掉Service,否則就會(huì)報(bào)錯(cuò)。
?
8.BindService
通過(guò)bindService()得到的Service是和啟動(dòng)源(Activity)綁定在一起的,在Activity退出的時(shí)候需要調(diào)用unbindService()進(jìn)行解綁定(停止)。
調(diào)用bindService()時(shí)會(huì)調(diào)用到目標(biāo)Service的onBind()函數(shù),通過(guò)IBinder接口實(shí)例,返回一個(gè)ServiceConnection對(duì)象給啟動(dòng)源。然后啟動(dòng)源可以通過(guò)ServiceConnection對(duì)象得到啟動(dòng)的Service對(duì)象
MyBindService.java
package com.example.test;import android.app.Service; import android.content.Intent; import android.content.ServiceConnection; import android.os.Binder; import android.os.IBinder; import android.util.Log;public class MyBindService extends Service{@Overridepublic void onCreate() {// TODO Auto-generated method stubLog.i("info", "BindService--onCreate()");super.onCreate();}public class MyBinder extends Binder{public MyBindService getService(){return MyBindService.this;}}@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubLog.i("info", "BindService--onBind()");return new MyBinder();}@Overridepublic void unbindService(ServiceConnection conn) {// TODO Auto-generated method stubLog.i("info", "BindService--unbindService()");super.unbindService(conn);}@Overridepublic void onDestroy() {// TODO Auto-generated method stubLog.i("info", "BindService--onDestroy()");super.onDestroy();}public void Play(){Log.i("info", "播放");}public void Pause(){Log.i("info", "暫停");}public void Pervious(){Log.i("info", "上一首");}public void next(){Log.i("info", "下一首");} }MainActivity.java
package com.example.test;import com.example.test.MyBindService.MyBinder;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.view.Menu; import android.view.View;public class MainActivity extends Activity {Intent intent1;Intent intent2;MyBindService service;ServiceConnection conn = new ServiceConnection() {@Override//當(dāng)服務(wù)跟啟動(dòng)源斷開的時(shí)候 會(huì)自動(dòng)回調(diào)public void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stub }@Override//當(dāng)服務(wù)跟啟動(dòng)源連接的時(shí)候 會(huì)自動(dòng)回調(diào)public void onServiceConnected(ComponentName name, IBinder binder) {// TODO Auto-generated method stubservice = ((MyBinder)binder).getService();}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void doClick(View v){switch (v.getId()) {case R.id.start:intent1 = new Intent(MainActivity.this, MyStartService.class);startService(intent1);break;case R.id.stop:stopService(intent1);break;case R.id.play:service.Play();break;case R.id.pause:service.Pause();break;case R.id.pervious:service.Pervious();break;case R.id.next:service.next();break;case R.id.bind://綁定Service:
//bindService()方法綁定服務(wù)
//Intent對(duì)象傳遞給bindService(),聲明需要啟動(dòng)的Service
//Context.BIND_AUTO_CREATE表明只要綁定存在,就自動(dòng)建立Service;同時(shí)也告知Android系統(tǒng),這個(gè)Service的重要程度與調(diào)用者相同 intent2 = new Intent(MainActivity.this, MyBindService.class);startService(intent2);bindService(intent2, conn, Service.BIND_AUTO_CREATE);//綁定了break;case R.id.unbind:unbindService(conn);break;}}@Overrideprotected void onDestroy() {// TODO Auto-generated method stub stopService(intent2);
//解綁Service:
//取消綁定使用unbindService()方法,并將ServiceConnnection對(duì)象傳遞給unbindService()方法。
//unbindService()方法調(diào)用成功后,系統(tǒng)并不會(huì)再次調(diào)用onServiceDisconnected()方法
//onServiceDisconnected()方法僅在意外斷開綁定時(shí)才被調(diào)用。 unbindService(conn);//解綁定super.onDestroy();}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu);return true;}}
?
轉(zhuǎn)載于:https://www.cnblogs.com/crazyzx/articles/5350862.html
總結(jié)
以上是生活随笔為你收集整理的6 四大组件之Service的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 学Python可以做Web前端开发吗?
- 下一篇: 岁月在变迁,彼此在成长。而我在流浪