‘壹’ android service 怎么一直运行的
android开发的过程中,每次调用startservice(intent)的时候,都会调用该service对象的onstartcommand(intent,int,int)方法,然后在onstartcommand方法中做一些处理。然后我们注意到这个函数有一个int的返回值
从android官方文档中,我们知道onstartcommand有4种返回值:
start_sticky:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onstartcommand(intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数intent将为null。
start_not_sticky:“非粘性的”。使用这个返回值时,如果在执行完onstartcommand后,服务被异常kill掉,系统不会自动重启该服务。
start_redeliver_intent:重传intent。使用这个返回值时,如果在执行完onstartcommand后,服务被异常kill掉,系统会自动重启该服务,并将intent的值传入。
start_sticky_compatibility:start_sticky的兼容版本,但不保证服务被kill后一定能重启。
现在的安卓手机,只要一长按home键,通常都会列出近期任务,这里可以干掉所有进程
所以一直不断的在后台运行是不行的,但是你可以通常广播来激活你的service
‘贰’ 如何让android的service一直在后台运行
按使用方式分类:
类别 区别
startService 启动的服务 主要用于启动一个服务执行后台任务,不进行通信。停止服务使用stopService
bindService 启动的服务 该方法启动的服务要进行通信。停止服务使用unbindService
startService 同时也 bindService 启动的服务 停止服务应同时使用stepService与unbindService
以上面三种方式启动的服务其生命周期也有区别,将在随后给出。
2、Service 与 Thread 的区别
很多时候,你可能会问,为什么要用 Service,而不用 Thread 呢,因为用 Thread 是很方便的,比起 Service
也方便多了,下面我详细的来解释一下。
1). Thread:Thread 是程序执行的最小单元,它是分配CPU的基本单位。可以用 Thread 来执行一些异步的操作。
2). Service:Service 是android的一种机制,当它运行的时候如果是Local Service,那么对应的 Service
是运行在主进程的 main 线程上的。如:onCreate,onStart 这些函数在被系统调用的时候都是在主进程的 main 线程上运行的。如果是Remote
Service,那么对应的 Service 则是运行在独立进程的 main 线程上。因此请不要把 Service
理解成线程,它跟线程半毛钱的关系都没有!
既然这样,那么我们为什么要用 Service 呢?其实这跟 android 的系统机制有关,我们先拿 Thread 来说。Thread 的运行是独立于
Activity 的,也就是说当一个 Activity 被 finish 之后,如果你没有主动停止 Thread 或者 Thread 里的 run
方法没有执行完毕的话,Thread 也会一直执行。因此这里会出现一个问题:当 Activity 被 finish 之后,你不再持有该 Thread
的引用。另一方面,你没有办法在不同的 Activity 中对同一 Thread 进行控制。
举个例子:如果你的 Thread 需要不停地隔一段时间就要连接服务器做某种同步的话,该 Thread 需要在 Activity
没有start的时候也在运行。这个时候当你 start 一个 Activity 就没有办法在该 Activity 里面控制之前创建的
Thread。因此你便需要创建并启动一个 Service ,在 Service 里面创建、运行并控制该 Thread,这样便解决了该问题(因为任何
Activity 都可以控制同一 Service,而系统也只会创建一个对应 Service 的实例)。
因此你可以把 Service 想象成一种消息服务,而你可以在任何有 Context 的地方调用
Context.startService、Context.stopService、
Context.bindService,Context.unbindService,来控制它,你也可以在 Service 里注册
BroadcastReceiver,在其他地方通过发送 broadcast 来控制它,当然这些都是 Thread 做不到的。
3、Service的生命周期1). 被启动的服务的生命周期:如果一个Service被某个Activity 调用 Context.startService
方法启动,那么不管是否有Activity使用bindService绑定或unbindService解除绑定到该Service,该Service都
在后台运行。如果一个Service被startService
方法多次启动,那么onCreate方法只会调用一次,onStart将会被调用多次(对应调用startService的次数),并且系统只会创建
Service的一个实例(因此你应该知道只需要一次stopService调用)。该Service将会一直在后台运行,而不管对应程序的
Activity是否在运行,直到被调用stopService,或自身的stopSelf方法。当然如果系统资源不足,android系统也可能结束服 务。
2). 被绑定的服务的生命周期:如果一个Service被某个Activity 调用 Context.bindService 方法绑定启动,不管调用
bindService 调用几次,onCreate方法都只会调用一次,同时onStart方法始终不会被调用。当连接建立之后,Service将会一直运行,除非调用
Context.unbindService 断开连接或者之前调用bindService 的 Context
不存在了(如Activity被finish的时候),系统将会自动停止Service,对应onDestroy将被调用。
3).
被启动又被绑定的服务的生命周期:如果一个Service又被启动又被绑定,则该Service将会一直在后台运行。并且不管如何调用,onCreate
始终只会调用一次,对应startService调用多少次,Service的onStart便会调用多少次。调用unbindService将不会停止
Service,而必须调用 stopService 或 Service的 stopSelf 来停止服务。
4). 当服务被停止时清除服务:当一个Service被终止(1、调用stopService;2、调用stopSelf;3、不再有绑定的连接(没有被启
动))时,onDestroy方法将会被调用,在这里你应当做一些清除工作,如停止在Service中创建并运行的线程。
特别注意:
1、你应当知道在调用 bindService 绑定到Service的时候,你就应当保证在某处调用 unbindService 解除绑定(尽管
Activity 被 finish 的时候绑定会自动解除,并且Service会自动停止);
2、你应当注意 使用 startService 启动服务之后,一定要使用
stopService停止服务,不管你是否使用bindService;
3、同时使用 startService 与 bindService 要注意到,Service
的终止,需要unbindService与stopService同时调用,才能终止 Service,不管 startService 与 bindService
的调用顺序,如果先调用 unbindService 此时服务不会自动终止,再调用 stopService 之后服务才会停止,如果先调用 stopService
此时服务也不会终止,而再调用 unbindService 或者 之前调用 bindService 的 Context 不存在了(如Activity 被
finish 的时候)之后服务才会自动停止;
4、当在旋转手机屏幕的时候,当手机屏幕在“横”“竖”变换时,此时如果你的 Activity 如果会自动旋转的话,旋转其实是 Activity
的重新创建,因此旋转之前的使用 bindService 建立的连接便会断开(Context 不存在了),对应服务的生命周期与上述相同。
5、在 sdk 2.0 及其以后的版本中,对应的 onStart 已经被否决变为了 onStartCommand,不过之前的 onStart
任然有效。这意味着,如果你开发的应用程序用的 sdk 为 2.0 及其以后的版本,那么你应当使用 onStartCommand 而不是 onStart。
4、startService 启动服务
想要用 startService 启动服务,不管Local 还是 Remote 我们需要做的工作都是一样简单。当然要记得在
Androidmanifest.xml 中注册 service。
根据上面的生命周期,我们便会给出 Service 中的代码框架:
package com.newcj.test;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class LocalService1 extends Service {
/**
* onBind 是 Service 的虚方法,因此我们不得不实现它。
* 返回 null,表示客服端不能建立到此服务的连接。
*/
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
对应生命周期系统回调函数上面已经说明,在对应地方加上适当的代码即可。下面是启动与停止 Service 的代码:
// 启动一个 Activity
startActivity(new Intent(this, LocalService1.class));
...
// 停止一个 Activity
stopService(new Intent(this, LocalService1.class));
对应的 Intent 为标志服务类的 Intent。
5、Local 与 Remote 服务绑定
同样记得在 Androidmanifest.xml 中注册 service
1). Local 服务绑定:Local 服务的绑定较简单,首先在 Service 中我们需要实现 Service 的抽象方法
onBind,并返回一个实现 IBinder 接口的对象。
Service 中的代码:
package com.newcj.test;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class LocalService extends Service {
/**
* 在 Local Service 中我们直接继承 Binder 而不是 IBinder,因为 Binder 实现了 IBinder
接口,这样我们可以少做很多工作。
* @author newcj
*/
public class SimpleBinder extends Binder{
/**
* 获取 Service 实例
* @return
*/
public LocalService getService(){
return LocalService.this;
}
public int add(int a, int b){
return a + b;
}
}
public SimpleBinder sBinder;
@Override
public void onCreate() {
super.onCreate();
// 创建 SimpleBinder
sBinder = new SimpleBinder();
}
@Override
public IBinder onBind(Intent intent) {
// 返回 SimpleBinder 对象
return sBinder;
}
}
上面的代码关键之处,在于 onBind(Intent) 这个方法 返回了一个实现了 IBinder 接口的对象,这个对象将用于绑定Service 的
Activity 与 Local Service 通信。下面是 Activity 中的代码:
package com.newcj.test;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
public class Main extends Activity {
private final static String TAG = "SERVICE_TEST";
private ServiceConnection sc;
private boolean isBind;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sc = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
LocalService.SimpleBinder sBinder = (LocalService.SimpleBinder)service;
Log.v(TAG, "3 + 5 = " + sBinder.add(3, 5));
Log.v(TAG, sBinder.getService().toString());
}
};
findViewById(R.id.btnBind).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
bindService(new Intent(Main.this, LocalService.class), sc,
Context.BIND_AUTO_CREATE);
isBind = true;
}
});
findViewById(R.id.btnUnbind).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(isBind){
unbindService(sc);
isBind = false;
}
}
});
}
}
在 Activity 中,我们通过 ServiceConnection 接口来取得建立连接 与
连接意外丢失的回调。bindService有三个参数,第一个是用于区分 Service 的Intent 与 startService 中的 Intent
一致,第二个是实现了 ServiceConnection 接口的对象,最后一个是 flag 标志位。有两个flag,BIND_DEBUG_UNBIND 与
BIND_AUTO_CREATE,前者用于调试(详细内容可以查看javadoc 上面描述的很清楚),后者默认使用。unbindService
解除绑定,参数则为之前创建的 ServiceConnection 接口对象。另外,多次调用 unbindService
来释放相同的连接会抛出异常,因此我创建了一个 boolean 变量来判断是否 unbindService 已经被调用过。
运行结果:
2). Remote 服务绑定:Remote 的服务绑定由于服务是在另外一个进程,因此需要用到 android 的 IPC
机制。这将又是一个很长的话题,因此,我打算写另外一篇 android 的 IPC 机制分析 ,并在其中进行详述,然后在这里更新链接,敬请关注。
特别注意:
1、Service.onBind如果返回null,则调用 bindService 会启动 Service,但不会连接上 Service,因此
ServiceConnection.onServiceConnected 不会被调用,但你任然需要使用 unbindService 函数断开它,这样
Service 才会停止。
6、创建前台服务
前台服务的优点上面已经说明,但设置服务为前台服务,我们需要注意在 sdk 2.0 及其以后版本使用的方法是 startForeground 与
stopForeground,之前版本使用的是 setForeground ,因此如果你应用程序的最低运行环境要求是
2.0,那么这里可以直接运用新方法,如果运行环境是2.0以下,那么为了保证向后兼容性,这里必须使用反射技术来调用新方法。
下面是我仿照 ApiDemos 重新敲的代码,对某些地方进行了修改,因此更具有说明性:
特别注意:
1、使用 startForeground ,如果 id 为 0 ,那么 notification 将不会显示。
7、在什么情况下使用 startService 或 bindService 或 同时使用startService 和 bindService
如果你只是想要启动一个后台服务长期进行某项任务那么使用 startService 便可以了。如果你想要与正在运行的 Service
取得联系,那么有两种方法,一种是使用 broadcast ,另外是使用 bindService ,前者的缺点是如果交流较为频繁,容易造成性能上的问题,并且
BroadcastReceiver 本身执行代码的时间是很短的(也许执行到一半,后面的代码便不会执行),而后者则没有这些问题,因此我们肯定选择使用
bindService(这个时候你便同时在使用 startService 和 bindService 了,这在 Activity 中更新 Service
的某些运行状态是相当有用的)。另外如果你的服务只是公开一个远程接口,供连接上的客服端(android 的 Service
是C/S架构)远程调用执行方法。这个时候你可以不让服务一开始就运行,而只用 bindService ,这样在第一次 bindService
的时候才会创建服务的实例运行它,这会节约很多系统资源,特别是如果你的服务是Remote Service,那么该效果会越明显(当然在 Service
创建的时候会花去一定时间,你应当注意到这点)。
8、在 AndroidManifest.xml 里 Service 元素的常见选项
android:name-------------服务类名
android:label--------------服务的名字,如果此项不设置,那么默认显示的服务名则为类名
android:icon--------------服务的图标
android:permission-------申明此服务的权限,这意味着只有提供了该权限的应用才能控制或连接此服务
android:process----------表示该服务是否运行在另外一个进程,如果设置了此项,那么将会在包名后面加上这段字符串表示另一进程的名字
android:enabled----------如果此项设置为 true,那么 Service 将会默认被系统启动,不设置默认此项为
false
android:exported---------表示该服务是否能够被其他应用程序所控制或连接,不设置默认此项为 false
‘叁’ Android 初学者 关于app关闭service一直运行 求各位指点迷津
Android5.0之前可以用双守护进程 fork一个子进程来守护主进程
白名单,微信QQ等等之所以能够存活,是因为系统商给了腾讯白名单,你调用清理内存时,并没有真正的清理
‘肆’ 安卓系统的app,我需要它一直在后台运行,我该怎么加锁才可以 关闭其
若是vivo手机,允许软件一直在后台运行 :
1、进入设置--电池--后台耗电管理--对应软件--选择“允许后台高耗电”(部分机型需进入设置--电池--后台高耗电--将对应的软件开启);
2、可以进入i管家--应用管理/软件管理--权限管理--权限--自启动--开启软件的自启权限;
3、进入多任务卡片界面,下拉软件加入到加速白名单;
可以参考设置加速白名单的方法:
OriginOS系统:调出卡片式后台,按住后台软件下滑即可加入白名单;
FuntouchOS10/iQOOUI及以上系统:调出卡片式后台,可按住卡片下拉锁定,也可以点右上角“=”图标--选择锁定;
FuntouchOS10以下系统:先调出快捷栏,然后按住需要设置白名单的软件向下拉,点击该软件上方的锁状图标,该软件即会加入白名单。
注:加入白名单后,后台软件右上角会显示锁状图标。
4、若软件被隐藏了,请把软件取消隐藏或移出原子隐私系统。
注:若是出现因软件异常占用内存,被智慧引擎强行关闭的情况,则是软件自身原因不支持设置。
更多疑惑,可以进入vivo官网--点击我的—在线客服,输入“人工”联系在线客服处理。
‘伍’ 如何让android的service一直在后台运行
首先来说,android是不存在一直运行后台服务的。而且,后天一直运行,就会消耗很大的手机资源的,因此也会影响手机的其他程序的使用的。
需要注意的事,手机系统运行的问题,以上的方法都是建立在手机系统够大的时候才行的。要不就会被很轻易的就清理掉了。
以上就是我的回答,希望可以帮到题主。
‘陆’ Android 之 Service(一)启动,绑定服务
Service(服务)一个运行在后台执行长时间运行的操作组件,它不提供任何用户界面,作为与Activity同级的组件,它依旧是运行在主线程中。
其它组件可以启动一个Service,当这个Service启动之后便会在后台执行,这里需要注意,由于是在主线程中,所以我们需要另外开启一个线程来执行我们的耗时操作。
此外,一个组件还可以与一个Service进行绑定来实现组件之间的交互,甚至可以执行IPC(Inter-Process Communication)进程间通信。
Service可以在后台执行很多任务,比如处理网络事务,播放音乐,文件读写或者与一个内容提供者交互,等等。
本地服务(Local)
该服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外本地服务因为是在同一进程因此不需要IPC,也不需要AIDL。相应bindService会方便很多,当主进程被Kill后,服务便会终止。一般使用在音乐播放器播放等不需要常驻的服务。
远程服务(Remote Service)
该服务是独立的进程,对应进程名格式为所在包名加上你指定的android:process字符串。一般定义方式 android:process=":service" 由于是独立的进程,因此在Activity所在进程被Kill的时候,该服务依然在运行,不受其他进程影响,有利于为多个进程提供服务具有较高的灵活性。由于是独立的进程,会占用一定资源,并且使用AIDL进行IPC比较麻烦。一般用于系统的Service,这种Service是常驻的。
startService启动的服务
用于启动一个服务执行后台任务,不与组件进行通信,停止服务使用stopService。 当一个应用组件比如activity通过调用startService()来启动一个服务的时候,服务便处于启动状态。一旦启动,服务可以在后台无限期地运行下去,即使当启动它的组件已经销毁。通常情况下,一个启动的service执行一个单一的操作并且不会返回任何结果给调用者。
bindService启动的服务
用于启动的服务需要进行通信。停止服务使用unbindService。 当一个应用组件通过调用bindService()来与一个服务绑定时,服务便处于绑定状态。一个绑定的服务提供了一个客户端-服务器端接口来允许组件与服务进行交互,发送请求,得到结果甚至通过IPC进程间通信来完成操作。只有当其它组件与服务进行绑定时,服务才会处于绑定状态。多个组件可以同时与服务绑定,但是当他们全部都解除绑定时,服务就会销毁。
2.BindService:
如果一个Service在某个Activity中被调用bindService方法启动,不论bindService被调用几次,Service的 onCreate 方法只会执行一次,同时 onStartCommand 方法始终不会调用。当建立连接后,Service会一直运行,除非调用unbindService来接触绑定、断开连接或调用该Service的Context不存在了(如Activity被Finish——即通过bindService启动的Service的生命周期依附于启动它的Context),系统在这时会自动停止该Service。
3.StartService AND BindService:
当一个Service在被启动(startService 的同时又被绑定(bindService ),该Service将会一直在后台运行,并且不管调用几次, onCreate 方法始终只会调用一次, onStartCommand 的调用次数与startService 调用的次数一致(使用bindService 方法不会调用 onStartCommand )。同时,调用unBindService 将不会停止Service,必须调用stopService 或Service自身的stopSelf 来停止服务。
4.停止Service:
当一个服务被终止(stopService 、stopSelf 、unbindService )时, onDestory 方法将会被调用——所以我们需要在该方法中清除一些工作(依附该Service生命周期上的,比如:停止在Service中创建并运行的线程)。
1.创建服务
如果你才用的是 startService的方式那么 onBind方法可以忽略
2.注册服务
3.开启服务
start:
bind
绑定服务,一般涉及到组件或进程之间的通信,既然需要通信,那么我们肯定需要一个连接,这里ServiceConnection就是我们所需要的连接,通过Ibinder的传递,我们可以获取到Service的Ibinder对象,从而进行相关操作。
关于粘性服务,这里需要提到 Service的onStartCommand返回值
andorid:name
adroid:exported
android:enabled
android:label
android:process
android:icon
android:permission
关于服务,当我们在应用开发中,如果需要长时间的在后台运行,独立完成某一些事情的情况下,请使用Service!
此文综合: http://www.jianshu.com/p/1e49e93c3ec8 以及自己的一些问题看法,用作学习,回顾之用。
Service 前台服务
请参看 紫豪 http://www.jianshu.com/p/5505390503fa