您好,登錄后才能下訂單哦!
Service簡(jiǎn)介:
Service是被設(shè)計(jì)用來(lái)在后臺(tái)執(zhí)行一些需要長(zhǎng)時(shí)間運(yùn)行的操作。
Android由于允許Service在后臺(tái)運(yùn)行,甚至在結(jié)束Activity后,因此相對(duì)來(lái)說(shuō),Service相比Activity擁有更高的優(yōu)先級(jí)。
創(chuàng)建Service:
要?jiǎng)?chuàng)建一個(gè)最基本的Service,需要完成以下工作:1)創(chuàng)建一個(gè)Java類,并讓其繼承Service 2)重寫onCreate()和onBind()方法
其中,onCreate()方法是當(dāng)該Service被創(chuàng)建時(shí)執(zhí)行的方法,onBind()是該Service被綁定時(shí)執(zhí)行的方法。
public class ExampleService extends Service{ @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); } }
當(dāng)創(chuàng)建了一個(gè)新的Service后,還必須在AndroidManifest.xml文件中對(duì)他進(jìn)行配置,需要在application節(jié)點(diǎn)內(nèi)包含一個(gè)Service標(biāo)記。
<service android:name=".ExampleService" android:enabled="true" android:permission="exam02.chenqian.com.servicedemo"></service>
當(dāng)然,如果你想要你自定義的Service僅能被自己編寫的該應(yīng)用程序使用,還可以在標(biāo)簽內(nèi)添加:
android:permission="exam02.chenqian.com.servicedemo"
讓Service執(zhí)行特定的任務(wù):
如果想要Service執(zhí)行特定的任務(wù),可以復(fù)寫Service的onStartCommand()方法,注意在API15之前為onStart()方法,現(xiàn)已不推薦,onStartCommand()方法的執(zhí)行為該Service onCreate()之后。
@Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); }
啟動(dòng)和停止Service:
顯式啟動(dòng)一個(gè)Service:
// 顯示啟動(dòng)ExampleService Intent intent = new Intent(this,ExampleService.class); // 啟動(dòng)ExampleService startService(intent);
為了方便觀察,我們可以在之前創(chuàng)建的自定義的Service類中的onStartCommand()方法中添加Log.i("ServiceState","-------------->is Running");
當(dāng)我們從MainActivity調(diào)用運(yùn)行時(shí),可以在Logcat中觀察到輸出: I/ServiceState: is Running
當(dāng)然,我們也可以停止一個(gè)Service,為了讓我們更清晰的觀察到效果,我們可以在ExampleService類中復(fù)寫onDestroy()方法:
@Override public void onDestroy() { Log.i("ServiceState","------------------>Destroy"); super.onDestroy(); }
可以在MainActivity中通過(guò)以下方式停止一個(gè)Service:
顯示停止一個(gè)Service:注意,寫這里時(shí)更換了一個(gè)Service,并將該自定義的Service定位MyService,已經(jīng)不是之前的ExampleService,不過(guò)您認(rèn)可按照自己之前的繼續(xù)編寫,畢竟方法都是一樣的;-)
//顯示關(guān)閉Service Intent serviceIntent = new Intent(MainActivity.this,MyService.class); //關(guān)閉Service stopService(serviceIntent);
注意Service的調(diào)用不可嵌套,因此無(wú)論Service被調(diào)用了多少次,對(duì)stopService()停止的一次調(diào)用就會(huì)終止它所匹配運(yùn)行中的Service。
由于Service具有較高的優(yōu)先級(jí),通常不會(huì)被運(yùn)行時(shí)終止,因此可以通過(guò)自終止來(lái)避免后臺(tái)運(yùn)行Service耗費(fèi)系統(tǒng)的資源。具體方法為在onStartCommand()方法中加入stopSelf();但是要注意的是這里的stopSelf()并不是直接終止Service,而是當(dāng)Service的所有功能或請(qǐng)求執(zhí)行完后,將Service停止掉,而不是等待系統(tǒng)回收,停止會(huì)調(diào)用onDestroy()銷毀該Service。
將Service綁定到Activity:
當(dāng)一個(gè)Service在一個(gè)Activity中被調(diào)用的時(shí)候,并不會(huì)隨著Activity的銷毀而銷毀,而是仍有可能繼續(xù)在后臺(tái)運(yùn)行著繼續(xù)占用系統(tǒng)的資源,因此如果實(shí)現(xiàn)當(dāng)Activity銷毀時(shí)自動(dòng)停止與其相關(guān)的服務(wù),將會(huì)極大的節(jié)約系統(tǒng)的資源占用,我們可以通過(guò)以下方式實(shí)現(xiàn)Activity與Service的綁定:
XML布局文件:在該布局文件中實(shí)現(xiàn)了四個(gè)按鈕,分別執(zhí)行啟動(dòng)Service、停止Service、綁定Service和解除綁定Service,清楚了吧:-)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="demo.chenqian.com.androidserverdemo.MainActivity"> <!-- 開啟Service --> <Button android:id="@+id/btnStartService" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="20dp" android:text="@string/startService"/> <!-- 關(guān)閉Service --> <Button android:id="@+id/btnStopService" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="20dp" android:text="@string/stopService"/> <!-- 綁定Service --> <Button android:id="@+id/btnBindService" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="20dp" android:text="@string/bindService"/> <!-- 解綁Service --> <Button android:id="@+id/btnUnbindService" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="20dp" android:text="@string/unbindService"/> </LinearLayout>
MyService類:
package demo.chenqian.com.androidserverdemo; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.support.annotation.Nullable; import android.util.Log; public class MyService extends Service{ /* 1、在下方我們定義了內(nèi)部類MyBinder,這就是為什么我們這里現(xiàn)在能定義binder的原因 2、這里我們定義binder成員變量的目的是為了在下文的MainActivity中實(shí)現(xiàn)轉(zhuǎn)型*/ private MyBinder binder = new MyBinder(); @Override public void onCreate() { Log.d("ServiceInfo","創(chuàng)建成功"); super.onCreate(); } @Nullable @Override public IBinder onBind(Intent intent) { Log.d("ServiceInfo","綁定成功"); return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("ServiceInfo","開始執(zhí)行"); return super.onStartCommand(intent, flags, startId); } @Override public boolean onUnbind(Intent intent) { Log.d("ServiceInfo","解綁成功"); return super.onUnbind(intent); } @Override public void onDestroy() { Log.d("ServiceInfo","銷毀成功"); super.onDestroy(); }
/*我們知道Android系統(tǒng)為了安全防護(hù)和整體的穩(wěn)定性,將每一個(gè)應(yīng)用程序隔離在相應(yīng)的獨(dú)立的“沙盒”之中,因此我們自定義的Service實(shí)際上是運(yùn)行在
用戶空間的,那么我們又有許多服務(wù)需要引用系統(tǒng)的Service,那么一個(gè)在用戶空間一個(gè)系統(tǒng)空間,他們之間如何實(shí)現(xiàn)通信呢,這就需要Binder了,
Binder是Android系統(tǒng)中實(shí)現(xiàn)不同進(jìn)程之間通信的一種方式,Binder本身有粘合劑的意思,Binder可以粘合Android系統(tǒng)中的四大組件,因此下方我 們?cè)贛yService類中新建了一個(gè)MyBinder內(nèi)部類,并讓其繼承Binder類,用來(lái)實(shí)現(xiàn)對(duì)MyService的獲取,這樣,你該知道為什我們上文要新建一個(gè)My-Binder的成員變量了吧 ^_^,在下方的MainActivity中你也可以看到相關(guān)實(shí)例的運(yùn)用,
例如
public void onServiceConnected(ComponentName name, IBinder service),注意這里的service是IBinder類型的,我們下方獲取MyService將會(huì)用到他*/ class MyBinder extends Binder{ MyService getService(){ Log.d("ServiceInfo","成功得到當(dāng)前服務(wù)實(shí)例"); return MyService.this; } } }
MainActivity類:
package demo.chenqian.com.androidserverdemo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Binder; import android.os.IBinder; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Context mContext; private Button btnStartService; private Button btnStopService; private Button btnBindService; private Button btnUnbindService; private MyService myService; private Intent serviceIntent; private boolean isBond; /*isBond該變量用來(lái)標(biāo)識(shí)當(dāng)前的Activity與Service是否正在綁定,因?yàn)槿绻贿M(jìn)行標(biāo)識(shí),如果Activity沒(méi)有 與Service進(jìn)行綁定,而執(zhí)行解除綁定的操作,會(huì)照成錯(cuò)誤或拋出異常,因?yàn)楫?dāng)接觸綁定時(shí)Android不允許綁定為null */ /*注意,這里我們新建了一個(gè)connection并重寫了相關(guān)方法,為什么我們要新建這個(gè)連接,那是因?yàn)樵谙路降慕壎ê徒饨? 方法即bind和unbind需要一個(gè)connection。我們復(fù)寫相關(guān)方法一是為了方便觀察,另一個(gè)是為了在連接成功或失去關(guān)閉 連接時(shí),執(zhí)行相關(guān)的自定義的任務(wù)或操作*/ private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.d("ServiceState","連接成功"); myService = ((MyService.MyBinder)service).getService(); } @Override public void onServiceDisconnected(ComponentName name) { Log.d("ServiceState","關(guān)閉連接"); //當(dāng)連接指向?qū)嵗秊閚ull沒(méi)有指引的連接的實(shí)例時(shí),好被虛擬機(jī)回收,降低占用的資源 myService = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化數(shù)據(jù) mContext = this; isBond = false; //引入需要用到的組件 btnStartService = (Button) findViewById(R.id.btnStartService); btnStopService = (Button) findViewById(R.id.btnStopService); btnBindService = (Button) findViewById(R.id.btnBindService); btnUnbindService = (Button) findViewById(R.id.btnUnbindService); //為按鈕添加單擊事件 btnStartService.setOnClickListener(this); btnStopService.setOnClickListener(this); btnBindService.setOnClickListener(this); btnUnbindService.setOnClickListener(this); } @Override protected void onStart() { serviceIntent = new Intent(this,MyService.class); super.onStart(); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.btnStartService: //開啟Service startService(serviceIntent); break; case R.id.btnStopService: //關(guān)閉Service stopService(serviceIntent); break; case R.id.btnBindService: //綁定Service isBond = bindService(serviceIntent,connection,Context.BIND_AUTO_CREATE); break; case R.id.btnUnbindService: //解綁Service,當(dāng)連接為null是解綁會(huì)報(bào)錯(cuò) if(isBond){ unbindService(connection); //如果解綁成功,則修改連接標(biāo)識(shí)為假 isBond = false; } break; } } }
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="demo.chenqian.com.androidserverdemo"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyService" android:enabled="true" android:permission="demo.chenqian.com.androidserverdemo"></service> </application> </manifest>
關(guān)于以后:
1、感覺(jué)Binder那塊還給大家解釋的不太清楚,以后再深入研究下補(bǔ)充完整
2、有時(shí)間會(huì)編寫一個(gè)簡(jiǎn)單的后臺(tái)播放音樂(lè)的實(shí)例提供給大家參考一下
以上所述是小編給大家介紹的詳解Android中的Service,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)歡迎給我留言,小編會(huì)及時(shí)回復(fù)大家的!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。