android service 自动解绑并销毁
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android service 自动解绑并销毁相关的知识,希望对你有一定的参考价值。
我在bind的service里面开启下载线程(onCreate方法里面),下载完成之后activity没有销毁,我也没有手动的解绑,但是下载线程结束之后服务就自动解绑并销毁了,为什么会这样?我试过,在onCreate方法里面不开启下载线程,service就不会解绑也不销毁,求解!
参考技术A 诚祺零零落落零零落落零零落落安卓服务service全解,生命周期,前台服务后台服务,启动注销绑定解绑,注册
全栈工程师开发手册 (作者:栾鹏)
python教程全解
定义服务(服务的生命周期)
调用context.startService()时依次执行 ->onCreate()- >onStartCommand()->Service running
调用context.stopService()时依次执行 ->onDestroy()
调用context.bindService()时依次执行->onCreate()->onBind()->Service running
调用context.onUnbind()时依次执行 -> onDestroy()
当绑定service和所有客户端解除绑定之后,Android系统将会销毁它,(除非它同时被onStartCommand()方法开启)。
因此,如果你的service是一个纯粹的绑定service,那么你不需要管理它的生命周期。
然而,如果你选择实现onStartCommand()回调方法,那么你必须显式地停止service,因为service此时被看做是开启的。
这种情况下,service会一直运行到它自己调用 stopSelf()或另一个组件调用stopService(),不论它是否和客户端绑定。
另外,如果你的service被开启并且接受绑定,那么当系统调用你的 onUnbind()方法时,如果你想要在下次客户端绑定的时候接受一个onRebind()的调用(而不是调用 onBind()),你可以选择在 onUnbind()中返回true。
onRebind()的返回值为void,但是客户端仍然在它的 onServiceConnected()回调方法中得到 IBinder 对象。
下图展示了这种service(被开启,还允许绑定)的生命周期:
代码示例:
代码中设计服务的生命周期,服务设置为前台服务和后台服务。
package com.lp.app.service;
import com.lp.app.Activity1;
import com.lp.app.R;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
//服务的生命周期
public class Service1 extends Service
public final static String action_name = "com.lp.action.service1";
public final static String key1 = "key1";
public final static String key2 = "key2";
//当服务被创建时,执行oncreat函数
@Override
public void onCreate()
Log.v("服务生命周期", "服务第一次被启动");
pausePlayback(); //将服务放置在后台。默认服务就是后台服务。前台服务是一个通知栏
startPlayback("显示标题","显示文本"); //打开一个通知栏,点击通知,可以将服务移动至前台
//onStartCommand为service的重新启动函数
@Override
public int onStartCommand(Intent intent, int flags, int startId)
//startBackgroundTask(intent, startId); //将服务设置到后台运行
//START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,重新启动后参数Intent将为null。
//START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
//START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将原来Intent的值传入。
//START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
//参数flags可以用来确定service的启动方式。START_FLAG_REDELIVERY表示Intent参数是由系统运行时在通过stopSelf显式停止service之前终止它而重新传递的。
//FLAF_RETRY表示service已经在异常终止后重新启动,如果service之前被设为START_STICKY,则会传入这个标志
Log.v("服务生命周期", "服务被其他窗口通过startService()启动");
return Service.START_STICKY;
public class MyBinder extends Binder
Service1 getService()
return Service1.this;
private final IBinder binder = new MyBinder();
@Override
public IBinder onBind(Intent intent)
// TODO 自动生成的方法存根
Log.v("服务生命周期", "一个客户端正在通过bindService()函数绑定到本服务");
return binder;
@Override
public void onRebind(Intent intent)
//在onUnbind()函数已经被调用过后执行
Log.v("服务生命周期", "一个客户端正在通过bindService()函数绑定到当前服务");
@Override
public boolean onUnbind(Intent intent)
Log.v("服务生命周期", "所有客户端已经通过unbindService()函数脱离绑定");
return true; //返回允许绑定
@Override
public void onStart(Intent intent,int startId)
Log.v("服务生命周期", "服务启动");
super.onStart(intent, startId);
@Override
public void onDestroy()
Log.v("服务生命周期", "服务销毁");
super.onDestroy();
//将一个service移动至前台
//(前台服务:会在通知一栏显示 ONGOING 的 Notification。当服务被终止的时候,通知一栏的 Notification 也会消失,这样对于用户有一定的通知作用)
//前台服务具有较高的优先级,能在内存不足时,不被杀死
private void startPlayback(String contenttitle, String contenttext)
int NOTIFICATION_ID = 1;
//创建一个当单击通知时将打开主activity的intent
Intent intent = new Intent(this, Activity1.class);
PendingIntent pi = PendingIntent.getActivity(this, 1, intent, 0);
//设置Notification UI参数
Notification notification = new Notification(R.drawable.icon,"启动app窗口", System.currentTimeMillis());
notification.setLatestEventInfo(this, contenttitle, contenttext, pi);
//设置notification为持续显示
notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;
//将service移到前台。
startForeground(NOTIFICATION_ID, notification);
//将service移动到后台
public void pausePlayback()
//移动到后台并移除Notification
stopForeground(true);
在manifest文件中注册服务
这里我们hi演示显式启动服务和隐式启动服务。所有这里处理设置服务的名称,还设置了触发条件
<!-- service注册服务,其中permission表示要想外部应用程序使用这个服务,必须要包含的自定义权限(只是个名称) -->
<service
android:name="com.lp.app.service.Service1"
android:permission="com.lp.my_service1_permission">
<intent-filter>
<action android:name="com.lp.action.service1"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
显式的启动和终止服务
Intent serviceIntent=null;
//显示启动一个服务
private void explicitStart()
serviceIntent = new Intent(this, Service1.class);
startService(serviceIntent);
//显式终止一个服务
private void explicitStop()
if(serviceIntent!=null)
stopService(serviceIntent);
隐式的启动和终止服务
隐式启动,相当于把自定义服务注册为系统服务,再以启动系统服务的方式启动自定义服务。
这种方式的和显式的启动和停止服务不同,而是通过intent触发指定名称的事件。而这个事件又触发了注册在manifest文件中的service,所以需要在manifest文件中注册服务时,设定触发源
//隐式的启动一个Service。相当于把自定义服务注册为系统服务,再以启动系统服务的方式启动自定义服务
private void implicitStart()
Intent intent = new Intent(Service1.action_name); //在注册服务是设置了intent-filter,所以启动这个,可以启动对应的服务
intent.putExtra(Service1.key1, "value1");
intent.putExtra(Service1.key2, "value2");
startService(intent);
//隐式终止一个服务
private void implicitStop()
Intent intent = new Intent(Service1.action_name);
stopService(intent);
绑定和解除绑定
//为Service绑定创建一个service连接
//service的引用
private Service1 serviceRef;
//处理service和 activity之间的连接
private ServiceConnection mConnection = new ServiceConnection()
//当建立连接时调用此函数
public void onServiceConnected(ComponentName className, IBinder service)
serviceRef = ((Service1.MyBinder)service).getService();
Log.v("服务绑定客户端", "服务绑定建立连接");
//当service意外断开时执行
public void onServiceDisconnected(ComponentName className)
serviceRef = null;
Log.v("服务绑定客户端", "服务绑定断开连接");
;
Intent bindIntent=null;
//绑定一个service和activity
private void bindToService()
bindIntent = new Intent(this, Service1.class);
bindService(bindIntent, mConnection, Context.BIND_AUTO_CREATE);
//BIND_AUTO_CREATE表示收到绑定请求的时候,如果服务尚未创建,则即刻创建,在系统内存不足需要先摧毁优先级组件来释放内存,且只有驻留该服务的进程成为被摧毁对象时,服务才被摧毁
//BIND_DEBUG_UNBIND通常用于调试场景中判断绑定的服务是否正确,但容易引起内存泄漏,因此非调试目的的时候不建议使用
//BIND_NOT_FOREGROUND表示系统将阻止驻留该服务的进程具有前台优先级,仅在后台运行,该标志位位于Froyo中引入
//解除一个绑定
private void unbindToService()
if (bindIntent!=null)
unbindService(mConnection);
以上是关于android service 自动解绑并销毁的主要内容,如果未能解决你的问题,请参考以下文章
android:当Activity和Service 都被销毁后,如何控制其中生成的线程?
在哪里停止/销毁 Android Service 类中的线程?