欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android Service中方法使用詳細(xì)介紹

 更新時間:2016年09月09日 11:43:31   作者:fengsehng  
這篇文章主要介紹了android service中方法使用詳細(xì)介紹的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下

 service作為四大組件值得我們的更多的關(guān)注

在Android中,Activity主要負(fù)責(zé)前臺頁面的展示,Service主要負(fù)責(zé)需要長期運行的任務(wù)。例如,一個從service播放音樂的音樂播放器,應(yīng)被設(shè)置為前臺運行,因為用戶會明確地注意它的運行.在狀態(tài)欄中的通知可能會顯示當(dāng)前的歌曲并且允許用戶啟動一個activity來與音樂播放器交互。

Service的兩種實現(xiàn)形式

1.非綁定

通過調(diào)用應(yīng)用程序組件(例如Activity)的startService()方法來啟動一個服務(wù).一旦啟動,服務(wù)就會在后臺一直運行,即使應(yīng)用程序組件此時被關(guān)閉.通常,已經(jīng)啟動的服務(wù)會處理一些單一功能,并且也不需要返回結(jié)果給調(diào)用者.例如,在網(wǎng)絡(luò)上下載或上傳文件.當(dāng)服務(wù)的工作處理結(jié)束,才會自己關(guān)閉服務(wù).

2.綁定(bind)

通過調(diào)用應(yīng)用程序組件的bindService()方法來綁定一個服務(wù).已綁定的服務(wù)會提供一個客戶端-服務(wù)端交互接口.該接口主要用來與應(yīng)用程序交互,發(fā)送請求,獲取結(jié)果,甚至通過IPC來訪問進(jìn)程.只要一個程序組件綁定服務(wù)就會運行綁定服務(wù),多個應(yīng)用程序組件可以同時時間綁定一個服務(wù).當(dāng)所有的應(yīng)用程序組件都解除綁定,該綁定服務(wù)器就會被銷毀.

實現(xiàn)service的方法介紹

onStartCommand()

  系統(tǒng)在其它組件比如activity通過調(diào)用startService()請求service啟動時調(diào)用這個方法.一旦這個方法執(zhí)行,service就啟動并且在后臺長期運行.如果你實現(xiàn)了它,你需要負(fù)責(zé)在service完成任務(wù)時停止它,通過調(diào)用stopSelf()或stopService().(如果你只想提供綁定,你不需實現(xiàn)此方法).

OnBind()

  當(dāng)組件調(diào)用bindService()想要綁定到service時(比如想要執(zhí)行進(jìn)程間通訊)系統(tǒng)調(diào)用此方法.在你的實現(xiàn)中,你必須提供一個返回一個IBinder來以使客戶端能夠使用它與service通訊,你必須總是實現(xiàn)這個方法,但是如果你不允許綁定,那么你應(yīng)返回null.

OnCreate()

  系統(tǒng)在service第一次創(chuàng)建時執(zhí)行此方法,來執(zhí)行只運行一次的初始化工作(在調(diào)用它方法如onStartCommand()或onBind()之前).如果service已經(jīng)運行,這個方法不會被調(diào)用.

OnDestroy()

  系統(tǒng)在service不再被使用并要銷毀時調(diào)用此方法.你的service應(yīng)在此方法中釋放資源,比如線程,已注冊的偵聽器,接收器等等.這是service收到的最后一個調(diào)用.

  如果一個組件通過調(diào)用startService()啟動一個service(最終導(dǎo)致onStartCommand()被調(diào)用),之后service會保持運行,直到它通過stopSelf()停止自己或另外的組件調(diào)用stopService()停止它.

service實現(xiàn)代碼

1.非綁定

新建一個MyService繼承自Service,并重寫父類的onCreate()、onStartCommand()和onDestroy()方法

public class MyIntentService extends IntentService { 
public MyIntentService() { 
super("MyIntentService"); 
} 
@Override 
protected void onHandleIntent(Intent intent) { 
// IntentService會使用單獨的線程來執(zhí)行該方法的代碼 
// 該方法內(nèi)執(zhí)行耗時任務(wù),比如下載文件,此處只是讓線程等待20秒 
long endTime = System.currentTimeMillis() + 20 * 1000; 
System.out.println("onStart"); 
while (System.currentTimeMillis() < endTime) { 
synchronized (this) { 
try { 
wait(endTime - System.currentTimeMillis()); 
} catch (InterruptedException e) { 
e.printStackTrace(); 
} 
} 
} 
System.out.println("----耗時任務(wù)執(zhí)行完成---"); 
} 
}

我們在布局文件中加入了兩個按鈕,一個用于啟動Service,一個用于停止Service。
然后打開或新建MainActivity作為程序的主Activity,在里面加入啟動Service和停止Service的邏輯,代碼如下所示:

public class MainActivity extends Activity implements OnClickListener { 
private Button startService; 
private Button stopService; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.activity_main); 
startService = (Button) findViewById(R.id.start_service); 
stopService = (Button) findViewById(R.id.stop_service); 
startService.setOnClickListener(this); 
stopService.setOnClickListener(this); 
} 
@Override 
public void onClick(View v) { 
switch (v.getId()) { 
case R.id.start_service: 
Intent startIntent = new Intent(this, MyService.class); 
startService(startIntent); 
break; 
case R.id.stop_service: 
Intent stopIntent = new Intent(this, MyService.class); 
stopService(stopIntent); 
break; 
default: 
break; 
} 
}

項目中的每一個Service都必須在AndroidManifest.xml中注冊才行,所以還需要編輯AndroidManifest.xml文件,代碼如下所示:

<application 
android:allowBackup="true" 
android:icon="@drawable/ic_launcher" 
android:label="@string/app_name" 
android:theme="@style/AppTheme" > 
…… 
<service android:name="com.example.servicetest.MyService" > 
</service> 
</application>

周期分析

onCreate()方法只會在Service第一次被創(chuàng)建的時候調(diào)用,如果當(dāng)前Service已經(jīng)被創(chuàng)建過了,不管怎樣調(diào)用startService()方法,onCreate()方法都不會再執(zhí)行。因此你可以再多點擊幾次Start Service按鈕試一次,每次都只會有onStartCommand()方法中的打印日志。

2.綁定的service

public class LocalService extends Service { 
// Binder given to clients 
private final IBinder mBinder = new LocalBinder(); 
// Random number generator 
private final Random mGenerator = new Random(); 
public class LocalBinder extends Binder { 
LocalService getService() { 
// 返回本service的實例到客戶端,于是客戶端可以調(diào)用本service的公開方法 
return LocalService.this; 
} 
} 
@Override 
public IBinder onBind(Intent intent) { 
return mBinder; 
} 
/**客戶端所要調(diào)用的方法*/ 
public int getRandomNumber() { 
return mGenerator.nextInt(100); 
} 
}

下面是一個綁定到LocalService并且在按鈕按下時調(diào)用getRandomNumber()的actvity的例子:

public class BindingActivity extends Activity { 
LocalService mService; 
boolean mBound = false; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.main); 
} 
@Override 
protected void onStart() { 
super.onStart(); 
// 綁定到類LocalService的實例 
Intent intent = new Intent(this, LocalService.class); 
bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 
} 
@Override 
protected void onStop() { 
super.onStop(); 
// 從service解除綁定 
if (mBound) { 
unbindService(mConnection); 
mBound = false; 
} 
} 
/** 當(dāng)按鈕按下時調(diào)用(在layout文件中定義的button并用android:onClick 屬性指定響應(yīng)到本方法) */ 
public void onButtonClick(View v) { 
if (mBound) { 
// 調(diào)用LocalService的一個方法 
// 然而,如果這個調(diào)用中有掛起操作,那么這個請求應(yīng)發(fā) 
// 生在另一個線程來避免拉低activity的性能. 
int num = mService.getRandomNumber(); 
Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show(); 
} 
} 
/** 定義service綁定的回調(diào),傳給bindService() 的*/ 
private ServiceConnection mConnection = new ServiceConnection() { 
@Override 
public void onServiceConnected(ComponentName className, 
IBinder service) { 
//我們已經(jīng)綁定到了LocalService,把IBinder進(jìn)行強(qiáng)制類型轉(zhuǎn)換并且獲取LocalService實例. 
LocalBinder binder = (LocalBinder) service; 
mService = binder.getService(); 
mBound = true; 
} 
@Override 
public void onServiceDisconnected(ComponentName arg0) { 
mBound = false; 
} 
}; 
}

service的周期函數(shù)

1、當(dāng)采用Context.startService()方法啟動服務(wù),與之有關(guān)的生命周期方法

onCreate()–> onStart()–> onDestroy()
onCreate()該方法在服務(wù)被創(chuàng)建時調(diào)用,該方法只會被調(diào)用一次,無論調(diào)用多少次startService()或bindService()方法,服務(wù)也只被創(chuàng)建一次。

onStart() 只有采用Context.startService()方法啟動服務(wù)時才會回調(diào)該方法。該方法在服務(wù)開始運行時被調(diào)用。多次調(diào)用startService()方法盡管不會多次創(chuàng)建服務(wù),但onStart() 方法會被多次調(diào)用。
onDestroy()該方法在服務(wù)被終止時調(diào)用。

2、 當(dāng)采用Context.bindService()方法啟動服務(wù),與之有關(guān)的生命周期方法

onCreate()–> onBind() –> onUnbind() –> onDestroy()
onBind()只有采用Context.bindService()方法啟動服務(wù)時才會回調(diào)該方法。該方法在調(diào)用者與服務(wù)綁定時被調(diào)用,當(dāng)調(diào)用者與服務(wù)已經(jīng)綁定,多次調(diào)用Context.bindService()方法并不會導(dǎo)致該方法被多次調(diào)用。

onUnbind()只有采用Context.bindService()方法啟動服務(wù)時才會回調(diào)該方法。該方法在調(diào)用者與服務(wù)解除綁定時被調(diào)用。

如果先采用startService()方法啟動服務(wù),然后調(diào)用bindService()方法綁定到服務(wù),再調(diào)用unbindService()方法解除綁定,最后調(diào)用bindService()方法再次綁定到服務(wù),觸發(fā)的生命周期方法如下:

onCreate()–>onStart()–>onBind()–>onUnbind()[重載后的方法需返回true–>onRebind()

那么如果我們既點擊了Start Service按鈕,又點擊了Bind Service按鈕會怎么樣呢?

這個時候你會發(fā)現(xiàn),不管你是單獨點擊Stop Service按鈕還是Unbind Service按鈕,Service都不會被銷毀,必要將兩個按鈕都點擊一下,Service才會被銷毀。也就是說,點擊Stop Service按鈕只會讓Service停止,點擊Unbind Service按鈕只會讓Service和Activity解除關(guān)聯(lián),一個Service必須要在既沒有和任何Activity關(guān)聯(lián)又處理停止?fàn)顟B(tài)的時候才會被銷毀。

Service和Thread的區(qū)別

主要就是因為Service的后臺概念。Thread我們大家都知道,是用于開啟一個子線程,在這里去執(zhí)行一些耗時操作就不會阻塞主線程的運行。而Service我們最初理解的時候,總會覺得它是用來處理一些后臺任務(wù)的,一些比較耗時的操作也可以放在這里運行,這就會讓人產(chǎn)生混淆了。但是,如果我告訴你Service其實是運行在主線程里的,所以是沒有任何關(guān)系的。

Service又有何用呢?

其實大家不要把后臺和子線程聯(lián)系在一起就行了,這是兩個完全不同的概念。

Android的后臺就是指,它的運行是完全不依賴UI的。即使Activity被銷毀,或者程序被關(guān)閉,只要進(jìn)程還在,Service就可以繼續(xù)運行。

比如說一些應(yīng)用程序,始終需要與服務(wù)器之間始終保持著心跳連接,就可以使用Service來實現(xiàn)。你可能又會問,前面不是剛剛驗證過Service是運行在主線程里的么?在這里一直執(zhí)行著心跳連接,難道就不會阻塞主線程的運行嗎?當(dāng)然會,但是我們可以在Service中再創(chuàng)建一個子線程,然后在這里去處理耗時邏輯就沒問題了。

使用service創(chuàng)建線程和activity直接創(chuàng)建線程的區(qū)別

Activity很難對Thread進(jìn)行控制,當(dāng)Activity被銷毀之后,就沒有任何其它的辦法可以再重新獲取到之前創(chuàng)建的子線程的實例。而且在一個Activity中創(chuàng)建的子線程,另一個Activity無法對其進(jìn)行操作。但是Service就不同了,所有的Activity都可以與Service進(jìn)行關(guān)聯(lián),然后可以很方便地操作其中的方法,即使Activity被銷毀了,之后只要重新與Service建立關(guān)聯(lián),就又能夠獲取到原有的Service中Binder的實例。因此,使用Service來處理后臺任務(wù),Activity就可以放心地finish,完全不需要擔(dān)心無法對后臺任務(wù)進(jìn)行控制的情況。

IntentService介紹

IntentService是Service的子類,比普通的Service增加了額外的功能。

先看Service本身存在兩個問題:

Service不會專門啟動一條單獨的進(jìn)程,Service與它所在應(yīng)用位于同一個進(jìn)程中;

Service也不是專門一條新線程,因此不應(yīng)該在Service中直接處理耗時的任務(wù);

二、IntentService特征

會創(chuàng)建獨立的worker線程來處理所有的Intent請求;

會創(chuàng)建獨立的worker線程來處理onHandleIntent()方法實現(xiàn)的代碼,無需處理多線程問題;

所有請求處理完成后,IntentService會自動停止,無需調(diào)用stopSelf()方法停止Service;

為Service的onBind()提供默認(rèn)實現(xiàn),返回null;

為Service的onStartCommand提供默認(rèn)實現(xiàn),將請求Intent添加到隊列中;

實現(xiàn)

public class MyIntentService extends IntentService { 
public MyIntentService() { 
super("MyIntentService"); 
} 
@Override 
protected void onHandleIntent(Intent intent) { 
// IntentService會使用單獨的線程來執(zhí)行該方法的代碼 
// 該方法內(nèi)執(zhí)行耗時任務(wù),比如下載文件,此處只是讓線程等待20秒 
long endTime = System.currentTimeMillis() + 20 * 1000; 
System.out.println("onStart"); 
while (System.currentTimeMillis() < endTime) { 
synchronized (this) { 
try { 
wait(endTime - System.currentTimeMillis()); 
} catch (InterruptedException e) { 
e.printStackTrace(); 
} 
} 
} 
System.out.println("----耗時任務(wù)執(zhí)行完成---"); 
} 
}

activity代碼

public void startIntentService(View source) { 
// 創(chuàng)建需要啟動的IntentService的Intent 
Intent intent = new Intent(this, MyIntentService.class); 
startService(intent); 
}

以上所述是小編給大家介紹的Android Service中方法使用詳細(xì)介紹,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

最新評論