Android Service
2017-10-25 本文已影响0人
百里漫步
- 本地服务(Local Service)
- 应用程序内部
- startService(启动服务)、stopService(在“启动源”或者 Activity 中停止服务)、stopSelf(在Service停止服务)、stopSelfResult(在Service中停止服务),后面两种都是服务的自我停止。
- bindService(绑定服务)、unbindService(解绑)
通过 startService 或者 bindService 都可以启动服务。
- 远程服务(Remote Service)
- Android系统内部的应用程序之间(不是手机之间)
- 定义 IBinder 接口,通过它,把数据暴露出来,然后把数据提供给启动源或者其他程序。
远程服务只能通过 IBinder 去启动服务。
我们知道一个Activity是有生命周期的,并且必须在配置文档中进行注册。而Service和Activity是类似的,有类似的生命周期,也必须注册。
继承关系:
Service 继承 ContextWrapper,Activity 继承 ContextThemeWrapper,二者共同拥有一个“祖宗类”——Context。
如图所示是 Service 的两种生命周期(分别以startService和bindService启动)。
Start方式特点:
- 服务跟启动源没有任何联系
- 无法得到服务对象
Bind方式特点: - 通过 Ibinder 接口实例,返回一个ServiceConnection对象给启动源
- 通过 ServiceConnection对象的相关方法可以得到Service对象
BindService: 支持数据回传。
什么时候使用Start?当服务不需要和启动源有任何关联的时候。这样有可能造成的结果:程序都退出了,但Service依然存在,为什么呢?因为二者没有关系。
不过,利用这种特性,也可以做一些特殊的应用,比如:UI不要了,但后台操作仍然继续的例子。但比较麻烦是就是:数据没办法回传了。
所以,既想让它们(服务和启动源)分离,又想得到回传数据,就需要将 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//当服务跟启动源断开的时候 会自动回调
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
@Override//当服务跟启动源连接的时候 会自动回调
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", "下一首");
}
}