- 本地服務(wù)(Local Service)
- 應(yīng)用程序內(nèi)部
- startService(啟動服務(wù))、stopService(在“啟動源”或者 Activity 中停止服務(wù))、stopSelf(在Service停止服務(wù))、stopSelfResult(在Service中停止服務(wù)),后面兩種都是服務(wù)的自我停止。
- bindService(綁定服務(wù))、unbindService(解綁)
通過 startService 或者 bindService 都可以啟動服務(wù)。
- 遠(yuǎn)程服務(wù)(Remote Service)
- Android系統(tǒng)內(nèi)部的應(yīng)用程序之間(不是手機之間)
- 定義 IBinder 接口,通過它,把數(shù)據(jù)暴露出來,然后把數(shù)據(jù)提供給啟動源或者其他程序。
遠(yuǎn)程服務(wù)只能通過 IBinder 去啟動服務(wù)。
我們知道一個Activity是有生命周期的,并且必須在配置文檔中進行注冊。而Service和Activity是類似的,有類似的生命周期,也必須注冊。
繼承關(guān)系:
Service 繼承 ContextWrapper,Activity 繼承 ContextThemeWrapper,二者共同擁有一個“祖宗類”——Context。
如圖所示是 Service 的兩種生命周期(分別以startService和bindService啟動)。
Start方式特點:
- 服務(wù)跟啟動源沒有任何聯(lián)系
- 無法得到服務(wù)對象
Bind方式特點: - 通過 Ibinder 接口實例,返回一個ServiceConnection對象給啟動源
- 通過 ServiceConnection對象的相關(guān)方法可以得到Service對象
BindService: 支持?jǐn)?shù)據(jù)回傳。
什么時候使用Start?當(dāng)服務(wù)不需要和啟動源有任何關(guān)聯(lián)的時候。這樣有可能造成的結(jié)果:程序都退出了,但Service依然存在,為什么呢?因為二者沒有關(guān)系。
不過,利用這種特性,也可以做一些特殊的應(yīng)用,比如:UI不要了,但后臺操作仍然繼續(xù)的例子。但比較麻煩是就是:數(shù)據(jù)沒辦法回傳了。
所以,既想讓它們(服務(wù)和啟動源)分離,又想得到回傳數(shù)據(jù),就需要將 Start 和 Bind 混合使用。
首先注冊service
然后,
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" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start:" />
<Button
android:id="@+id/start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="doClick"
android:text="StartService" />
<Button
android:id="@+id/stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="doClick"
android:text="StopService" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bind:" />
<Button
android:id="@+id/bind"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="doClick"
android:text="BindService" />
<Button
android:id="@+id/play"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="doClick"
android:text="播放" />
<Button
android:id="@+id/pause"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="doClick"
android:text="暫停" />
<Button
android:id="@+id/next"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="doClick"
android:text="下一首" />
<Button
android:id="@+id/pervious"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="doClick"
android:text="上一首" />
<Button
android:id="@+id/unbind"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="doClick"
android:text="UnBindService" />
</LinearLayout>
MainActivity.java
import com.example.servicedemo.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ù)跟啟動源斷開的時候 會自動回調(diào)
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
@Override//當(dāng)服務(wù)跟啟動源連接的時候 會自動回調(diào)
public void onServiceConnected(ComponentName name, IBinder binder) {
// TODO Auto-generated method stub
service = ((MyBinder)binder).getService();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.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:
intent2 = new Intent(MainActivity.this, MyBindService.class);
startService(intent2);
bindService(intent2, conn, Service.BIND_AUTO_CREATE);
break;
case R.id.unbind:
unbindService(conn);
break;
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
stopService(intent2);
unbindService(conn);
super.onDestroy();
}
@Override
public 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;
}
}
MyStartService.java
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class MyStartService extends Service {
@Override
public void onCreate() {
// TODO Auto-generated method stub
Log.i("info", "Service--onCreate()");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.i("info", "Service--onStartCommand()");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.i("info", "Service--onDestroy()");
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.i("info", "Service--onBind()");
return null;
}
}
MyBindService.java
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{
@Override
public void onCreate() {
// TODO Auto-generated method stub
Log.i("info", "BindService--onCreate()");
super.onCreate();
}
public class MyBinder extends Binder{
public MyBindService getService(){
return MyBindService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.i("info", "BindService--onBind()");
return new MyBinder();
}
@Override
public void unbindService(ServiceConnection conn) {
// TODO Auto-generated method stub
Log.i("info", "BindService--unbindService()");
super.unbindService(conn);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.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", "下一首");
}
}