android 系统开发开发怎么让个推服务不被手机系统杀掉

[Android] Service服务详解以及怎么使service服务不被杀死 - Android当前位置:& &&&[Android] Service服务详解以及怎么使service服务不[Android] Service服务详解以及怎么使service服务不被杀死&&网友分享于:&&浏览:0次[Android] Service服务详解以及如何使service服务不被杀死排版上的细节有些不好看,主要是我用的MarkDown编辑器预览和这里的不一样,在那个上面的样式很舒服。这里要改的地方太多就不想改了,将就看吧。下次写的时候注意。还有看到错误给我提啊。:
服务是一个应用程序组件,可以在后台执行长时间运行的操作,不提供用户界面。一个应用程序组件可以启动一个服务,它将继续在后台运行,即使用户切换到另一个应用程序。此外,一个组件可以绑定到一个服务与它交互,甚至执行进程间通信(IPC)。例如,一个服务可能处理网络通信,播放音乐,执行文件I/O,或与一个内容提供者交互,都在后台执行。
一个服务本质上讲有两种形式:
Started 启动的
started形式的服务是指当一个应用组件(比如activity)通过startService()方法开启的服务。一旦开启,该服务就可以无限期地在后台运行,哪怕开启它的组件被销毁掉。通常,开启的服务执行一个单独的操作且并不向调用者返回一个结果。比如,可能从网络进行下载或者上传一个文件。当任务完成,服务就该自我停止。
Bound 绑定的
bound形式的服务是指一个应用组件通过调用 bindService() 方法与服务绑定。一个绑定的服务提供一个客户-服务端接口,以允许组件与服务交互,发送请求,获得结果,甚至执行进程间通信。一个绑定的服务只和与其绑定的组件同时运行。多个组件可以同时绑定到一个服务,但当全部接触绑定后,服务就被销毁。
虽然分这两类,但是一个服务可以同时使用这两种方式——可以用started无限期的运行,同时允许绑定。只需要在服务中实现两个回调方法:onStartCommand()允许组件开启服务,onBind()允许绑定。
不论应用程序是怎么起服务的,任何应用程序都可以用这个服务。同样的,任何组件可以使用一个Activity通过传递Intent开启服务。你也可以在配置文件设置服务为私有来防止其他应用访问该服务。
注意:一个服务在进程中的主线程运行——一个服务不会创建自己的线程,也不会在另外的进程运行(除非另外指定)。这意味着,如果服务需要做一些频繁占用CPU的工作或者会发生阻塞的操作,你需要在服务中另开线程执行任务。这可以降低产生ANR的风险,提高用户体验。
创建一个服务需要建立一个Service相关的子类,然后需要实现一些回调方法,好在不同的生命周期内做对应处理和绑定服务,比较重要的方法如下:
onStartCommand() 当其他组件,如 activity 请求服务启动时,系统会调用这个方法。一旦这个方法执行,服务就开始并且无限期的执行。如果实现这个方法,当这个服务完成任务后,需要你来调用 stopSelf() 或者 stopService() 停掉服务。如果只想提供绑定,不需要自己实现这个方法。
onBind() 当有其他组件想通过 bindService() 方法绑定这个服务时系统就会调用此方法。在实现的方法里面,必须添加一个供客户端使用的接口通过返回一个IBinder来与服务通信,这个方法必须实现。当然不想允许绑定的话,返回null即可。
onCreate() 服务第一次建立的时候会调用这个方法,执行一次性设置程序,在上面2个方法执行前调用。如果服务已存在,则不执行该方法。
onDestroy() 服务不再使用则使用该方法。服务应该实现这个方法来清理诸如线程,注册的监听器等资源。这是最后调用的方法。
安卓系统只会在内存占用很高,必须恢复系统资源供当前运行程序的情况下强制停掉一个运行中的服务。如果服务绑定在当前运行的程序中,就几乎不会被杀掉,如果服务声明了在前台运行(其实在后台,只是给系统一个错的信息来提高优先级),就几乎不会被杀掉。另外,如果一个服务正在运行,且运行了很久,系统就会根据运行时间把其排在后台任务列表的后面,则这个服务很容易被杀掉。根据onStartCommand() 的返回值设置,服务被杀掉后仍可以在资源充足的条件下立即重启。
是用一个服务好还是开一个线程好一个服务就是一个可以忽略交互,在后台独立运行的组件,如果你需要这样就用服务如果你需要在用户与程序交互时在主线程外执行任务,那就开个线程吧。比如想播放音乐,但只在程序运行时播放,你可能在 onCreate() 开一个线程,在 onStart() 中开启它,在 onStop() 停止它。也可以考虑使用AsyncTask或者HandlerThread取代一般的线程。记住,如果使用一个服务,它还是默认在主线程中运行,如果会发生阻塞,还是要在服务中另开线程的。
在 manifest 文件声明服务
要使用服务就必须在 manifest 文件声明要用的所有服务,只用在&application&标签内添加子标签&service&即可。
&manifest ...&
&application ...&
&service android:name=&.ExampleService&
android:enabled=[&true& | &false&]
android:exported=[&true& | &false&]
android:isolatedProcess=[&true& | &false&]
android:label=&string resource&
android:icon=&drawable resource&
android:permission=&string&
android:process=&string& &
&/service&
&/application&
&/manifest&
下面对service标签属性做说明
android:name 你所编写的服务类的类名,可填写完整名称,包名+类名,如com.example.test.ServiceA,也可以忽略包名,用.开头,如.ServiceA,因为在manifest文件开头会定义包名,它会自己引用。
一旦你发布应用,你就不能改这个名字(除非设置android:exported=&false&),另外name没有默认值,必须定义。
android:enabled 是否可以被系统实例化,默认为true
因为父标签&application&也有enable属性,所以必须两个都为默认值true的情况下服务才会被激活,否则不会激活。
android:exported 其他应用能否访问该服务,如果不能,则只有本应用或有相同用户ID的应用能访问。当然除了该属性也可以在下面permission中限制其他应用访问本服务。
这个默认值与服务是否包含意图过滤器intent filters有关。如果一个也没有则为false
android:isolatedProcess 设置true意味着,服务会在一个特殊的进程下运行,这个进程与系统其他进程分开且没有自己的权限。与其通信的唯一途径是通过服务的API(binding and starting)。
android:label 可以显示给用户的服务名称。如果没设置,就用&application&的lable。不管怎样,这个值是所有服务的意图过滤器的默认lable。定义尽量用对字符串资源的引用。
android:icon 类似label,是图标,尽量用drawable资源的引用定义。
android:permission 是一个实体必须要运行或绑定一个服务的权限。如果没有权限,startService(),bindService()或stopService()方法将不执行,Intent也不会传递到服务。
如果属性未设置,会由&application&权限设置情况应用到服务。如果两者都未设置,服务就不受权限保护。
android:process 服务运行所在的进程名。通常为默认为应用程序所在的进程,与包名同名。&application&元素的属性process可以设置不同的进程名,当然组件也可设置自己的进程覆盖应用的设置。
如果名称设置为冒号:开头,一个对应用程序私有的新进程会在需要时和运行到这个进程时建立。如果名称为小写字母开头,服务会在一个相同名字的全局进程运行,如果有权限这样的话。这允许不同应用程序的组件可以分享一个进程,减少了资源的使用。
创建“启动的”服务
启动的(started)服务由startService(Intent)方法启动,在服务中的onStartCommand()方法里获得Intent信息。关闭则由服务自己的方法stopSelf()或者由启动服务的地方调用stopService(Intent)方法来关闭。并不会因为启动服务的应用程序销毁而关闭。
示例,一个应用需要保存数据到远程数据库,这时启动一个服务,通过创建启动的服务给服务传递数据,由服务执行保存行为,行为结束再自我销毁。因为服务跟启动它的应用在一个进程的主线程中,所以对于耗时的操作要起一个新的线程去做。
//activity中
Intent intent = new Intent(MainActivity.this, ServiceA.class);
intent.putExtra(&name&, strName);
startService(intent);
//service中
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
// 获取数据
String strName = intent.getStringExtra(&name&);
// ... 数据库操作
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
耗时的操作
return Service.START_STICKY;
写服务有2种,继承service或者IntentService。后者是前者的子类。前者包含上面介绍的各种方法,用于普通的服务。后者可以自己开一个工作线程一个接一个处理多个请求。
继承IntentService
大多数服务不需要同时处理多个请求,继承IntentService是最好的选择
IntentService处理流程
创建默认的一个worker线程处理传递给onStartCommand()的所有intent,不占据应用的主线程
创建一个工作队列一次传递一个intent到你实现的onHandleIntent()方法,避免了多线程
在所以启动请求被处理后自动关闭服务,不需要调用stopSelf()
默认提供onBind()的实现,并返回null
默认提供onStartCommand()的实现,实现发送intent到工作队列再到你的onHandleIntent()方法实现。
这些都加入到IntentService中了,你需要做的就是实现构造方法和onHandleIntent(),如下:
public class HelloIntentService extends IntentService {
* A constructor is required, and must call the super IntentService(String)
* constructor with a name for the worker thread.
public HelloIntentService() {
super(&HelloIntentService&);
* The IntentService calls this method from the default worker thread with
* the intent that started the service. When this method returns, IntentService
* stops the service, as appropriate.
protected void onHandleIntent(Intent intent) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
long endTime = System.currentTimeMillis() + 5*1000;
while (System.currentTimeMillis() & endTime) {
synchronized (this) {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
如果需要重写其他回调方法,如onCreate(),onStartCommand()等,一定要调用super()方法,保证IntentService正确处理worker线程,只有onHandleIntent()和onBind()不需要这样。如:
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, &service starting&, Toast.LENGTH_SHORT).show();
return super.onStartCommand(intent,flags,startId);
继承Service
继承Service就可以实现对请求多线程的处理,前面介绍了service的生命周期,可以按照生命周期实现方法。就不放示例了。
onStartCommand()的返回值返回一个整型值,用来描述系统在杀掉服务后是否要继续启动服务,返回值有三种:
START_NOT_STICKY 系统不重新创建服务,除非有将要传递来的intent。这是最安全的选项,可以避免在不必要的时候运行服务。
START_STICKY 系统重新创建服务并且调用onStartCommand()方法,但并不会传递最后一次传递的intent,只是传递一个空的intent。除非存在将要传递来的intent,那么就会传递这些intent。这个适合播放器一类的服务,不需要执行命令,只需要独自运行,等待任务。
START_REDELIVER_INTENT 系统重新创建服务并且调用onStartCommand()方法,传递最后一次传递的intent。其余存在的需要传递的intent会按顺序传递进来。这适合像下载一样的服务,立即恢复,积极执行。
如果想从服务获得结果,可以用广播来处理
创建“绑定的”服务
用bindService()方法将应用组件绑定到服务,建立一个长时间保持的联系。
如果需要在activity或其他组件和服务交互或者通过进程间通信给其他应用程序提供本应用的功能,就需要绑定的服务。
建立一个绑定的服务需要实现onBind()方法返回一个定义了与服务通信接口的IBinder对象。其他应用程序组件可以调用bindService()方法获取接口并且调用服务上的方法。
创建一个绑定的服务,第一件事就是定义一个说明客户端与服务通信方式的接口。这个接口必须是IBinder的实现,并且必须要从onBind()方法返回。一旦客户端接收到了IBinder,就可以通过这个接口进行交互。
多个客户端可以绑定到一个服务,可以用unbindService()方法解除绑定,当没有组件绑定在服务上,这个服务就会被销毁。
//activity中
private ServiceConnection connB = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
Log.v(tag, &Service B disconnected&);
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
Log.v(tag, &Service B connected&);
MyBinderB binder = (MyBinderB)
ServiceB SB = binder.getService();
SB.showLog();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Intent a = new Intent(MainActivity.this, ServiceB.class);
bindService(a, connB, BIND_AUTO_CREATE);
//ServiceB
public class ServiceB extends Service {
public void showLog() {
Log.i(tag, &serviceB--&showLog()&);
public class MyBinderB extends Binder {
public ServiceB getService() {
return ServiceB.
private MyBinderB myBinderB = new MyBinderB();
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return myBinderB;
启动前台服务
前台服务是被认为是用户已知的正在运行的服务,当系统需要释放内存时不会优先杀掉该进程。前台进程必须发一个notification在状态栏中显示,直到进程被杀死。因为前台服务会一直消耗一部分资源,但不像一般服务那样会在需要的时候被杀掉,所以为了能节约资源,保护电池寿命,一定要在建前台服务的时候发notification,提示用户。当然,系统提供的方法就是必须有notification参数的,所以不要想着怎么把notification隐藏掉。
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification noti = new Notification.Builder(this)
.setContentTitle(&Title&)
.setContentText(&Message&)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pendingIntent)
startForeground(12346, noti);
return Service.START_STICKY;
startForeground()方法就是将服务设为前台服务。参数12346就是这个通知唯一的id,只要不为0即可。
服务的生命周期
启动的服务: startService()-&onCreate()-&onStartCommand()-&running-&stopService()/stopSelf()-&onDestroy()-&stopped 其中,服务未运行时会调用一次onCreate(),运行时不调用。
绑定的服务: bindService()-&onCreate()-&onBind()-&running-&onUnbind()-&onDestroy()-&stopped
服务起始于onCreate(),终止于onDestory()服务的开关过程,只有onStartCommand()可多次调用,其他在一个生命周期只调用一次。
这两个过程并不完全独立,也可以绑定一个由startService()启动过的服务
关于怎样让服务不被杀死
这个倒是有点流氓软件的意思,但有些特定情况还是需要服务能保持开启不被杀死,当然这样做我还是在程序里添加了关闭服务的按钮,也就是开启了就杀不死,除非在软件里关闭。
服务不被杀死分3种来讨论1.系统根据资源分配情况杀死服务2.用户通过settings-&Apps-&Running-&Stop方式杀死服务3.用户通过settings-&Apps-&Downloaded-&Force Stop方式杀死服务
第一种情况:
用户不干预,完全靠系统来控制,办法有很多。比如onStartCommand()方法的返回值设为START_STICKY,服务就会在资源紧张的时候被杀掉,然后在资源足够的时候再恢复。当然也可设置为前台服务,使其有高的优先级,在资源紧张的时候也不会被杀掉。
第二种情况:
用户干预,主动杀掉运行中的服务。这个过程杀死服务会通过服务的生命周期,也就是会调用onDestory()方法,这时候一个方案就是在onDestory()中发送广播开启自己。这样杀死服务后会立即启动。如下:
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
mBR = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent a = new Intent(ServiceA.this, ServiceA.class);
startService(a);
mIF = new IntentFilter();
mIF.addAction(&listener&);
registerReceiver(mBR, mIF);
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Intent intent = new Intent();
intent.setAction(&listener&);
sendBroadcast(intent);
unregisterReceiver(mBR);
当然,从理论上来讲这个方案是可行的,实验一下也可以。但有些情况下,发送的广播在消息队列中排的靠后,就有可能服务还没接收到广播就销毁了(这是我对实验结果的猜想,具体执行步骤暂时还不了解)。所以为了能让这个机制完美运行,可以开启两个服务,相互监听,相互启动。服务A监听B的广播来启动B,服务B监听A的广播来启动A。经过实验,这个方案可行,并且用360杀掉后几秒后服务也还是能自启的。到这里再说一句,如果不是某些功能需要的服务,不建议这么做,会降低用户体验。
第三种情况:
强制关闭就没有办法。这个好像是从包的level去关的,并不走完整的生命周期。所以在服务里加代码是无法被调用的。处理这个情况的唯一方法是屏蔽掉force stop和uninstall按钮,让其不可用。方法自己去找吧。当然有些手机自带的清理功能就是从这个地方清理的,比如华为的清理。所以第三种情况我也没有什么更好的办法了。
最后再说一句,别在这上面太折腾,弄成流氓软件就不好了。我就是讨厌一些软件乱发通知,起服务才转而用iPhone的。不过下一代Android好像可以支持用户选择是否开启软件设置的权限了,倒是可以期待一下。推荐一篇文章:
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 1234567891011 Copyright & &&版权所有trackbacks-0
Service简介
1、Service
每个Service必须在manifest中 通过&service&来声明。
可以通过contect.startservice和contect.bindserverice来启动。
和其他的应用组件一样,运行在进程的主线程中。这就是说如果service需要很多耗时或者阻塞的操作,需要在其子线程中实现(或者用系统提供的IntentService,它继承了Service,它处理数据是用自身新开的线程)。【当然你也可以在新的线程中startService,这样Service就不是在MainThread了】
2、本地服务 Local Service 用于应用程序内部
它可以启动并运行,直至有人停止了它或它自己停止。在这种方式下,它以调用Context.startService()启动,而以调用Context.stopService()结束。它可以调用Service.stopSelf() 或
Service.stopSelfResult()来自己停止。不论调用了多少次startService()方法,你只需要调用一次stopService()来停止服务。
【用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好】
3、远程服务 Remote Service 用于android系统内部的应用程序之间
它可以通过自己定义并暴露出来的接口进行程序操作。客户端建立一个到服务对象的连接,并通过那个连接来调用服务。连接以调用Context.bindService()方法建立,以调Context.unbindService()关闭。
多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。
【可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可】
4、Service的生命周期
5、Service运行方式
以startService()启动服务,系统将通过传入的Intent在底层搜索相关符合Intent里面信息的service。如果服务没有启动则先运行onCreate,然后运行onStartCommand
(可在里面处理启动时传过来的Intent和其他参数),直到明显调用stopService或者stopSelf才将停止Service。无论运行startService多少次,只要调用一次stopService或者stopSelf,Service都会停止。使用stopSelf(int)方
法可以保证在处理好intent后再停止。onStartCommand在2.0后被引入用于service的启动函数
以bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止。onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务
已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。采用Context.bindService()方法启动服务时只能调用onUnbind()方法解除调用者与服务解除,服务结束时会调用onDestroy()方法。
5、拥有service的进程具有较高的优先级
官方文档告诉我们,Android系统会尽量保持拥有service的进程运行,只要在该service已经被启动(start)或者客户端连接(bindService)到它。当内存不足时,需要保持,拥有service的进程具有较高的优先级。
1. 如果service正在调用onCreate,onStartCommand或者onDestory方法,那么用于当前service的进程则变为前台进程以避免被killed。
2. 如果当前service已经被启动(start),拥有它的进程则比那些用户可见的进程优先级低一些,但是比那些不可见的进程更重要,这就意味着service一般不会被killed.
3. 如果客户端已经连接到service (bindService),那么拥有Service的进程则拥有最高的优先级,可以认为service是可见的。
4. 如果service可以使用startForeground(int, Notification)方法来将service设置为前台状态,那么系统就认为是对用户可见的,并不会在内存不足时killed。
5.&如果有其他的应用组件作为Service,Activity等运行在相同的进程中,那么将会增加该进程的重要性。
6、保证service不被杀掉
onStartCommand方法,返回START_STICKY
StartCommond几个常量参数简介:
1、START_STICKY
在运行onStartCommand后service进程被kill后,那将保留在开始状态,但是不保留那些传入的intent。不久后service就会再次尝试重新创建,因为保留在开始状态,在创建 & &
service后将保证调用onstartCommand。如果没有传递任何开始命令给service,那将获取到null的intent。
2、START_NOT_STICKY
在运行onStartCommand后service进程被kill后,并且没有新的intent传递给它。Service将移出开始状态,并且直到新的明显的方法(startService)调用才重新创建。因为如果没
有传递任何未决定的intent那么service是不会启动,也就是期间onstartCommand不会接收到任何null的intent。
3、START_REDELIVER_INTENT
在运行onStartCommand后service进程被kill后,系统将会再次启动service,并传入最后一个intent给onstartCommand。直到调用stopSelf(int)才停止传递intent。如果在被kill后还有未处理好的intent,
那被kill后服务还是会自动启动。因此onstartCommand不会接收到任何null的intent。
@Override&&
public&int&onStartCommand(Intent&intent,&int&flags,&int&startId)&{&&
&&&&flags&=&START_STICKY;&&
&&&&return&super.onStartCommand(intent,&flags,&startId);&&
【结论】&手动返回START_STICKY,亲测当service因内存不足被kill,当内存又有的时候,service又被重新创建,比较不错,但是不能保证任何情况下都被重建,比如进程被干掉了....
提升service优先级
&service&&
&&&&android:name="com.dbjtech.acbxt.waiqin.UploadService"&&
&&&&android:enabled="true"&&&&
&&&&&intent-filter&android:priority="1000"&&&&
&&&&&&&&&action&android:name="com.dbjtech.myservice"&/&&&
&&&&&/intent-filter&&&
&/service&&&
【结论】目前看来,priority这个属性貌似只适用于broadcast,对于Service来说可能无效
提升service进程优先级
Android中的进程是托管的,当系统进程空间紧张的时候,会依照优先级自动进行进程的回收。Android将进程分为6个等级,它们按优先级顺序由高到低依次是:
& &1.前台进程( FOREGROUND_APP)
& &2.可视进程(VISIBLE_APP )
& &3. 次要服务进程(SECONDARY_SERVER )
& &4.后台进程 (HIDDEN_APP)
& &5.内容供应节点(CONTENT_PROVIDER)
& &6.空进程(EMPTY_APP)
当service运行在低内存的环境时,将会kill掉一些存在的进程。因此进程的优先级将会很重要,可以使用startForeground将service放到前台状态。这样在低内存时被kill的几率会低一些。
在onStartCommand方法内添加如下代码:
&Notification&notification&=&new&Notification(R.drawable.ic_launcher,&&
&getString(R.string.app_name),&System.currentTimeMillis());&&
&PendingIntent&pendingintent&=&PendingIntent.getActivity(this,&0,&&
&new&Intent(this,&AppMain.class),&0);&&
&notification.setLatestEventInfo(this,&"uploadservice",&"请保持程序在后台运行",&&
&pendingintent);&&
&span&style="color:#ff0000;"&&startForeground(0x111,&notification);&/span&&&
注意在onDestroy里还需要stopForeground(true),运行时在下拉列表会看到自己的APP在:
【结论】如果在极度极度低内存的压力下,该service还是会被kill掉,并且不一定会restart
onDestroy方法里重启service
service +broadcast &方式,就是当service走ondestory的时候,发送一个自定义的广播,当收到广播的时候,重新启动service;
&receiver&android:name="com.dbjtech.acbxt.waiqin.BootReceiver"&&&&
&&&&&intent-filter&&&
&&&&&&&&&action&android:name="android.intent.action.BOOT_COMPLETED"&/&&&
&&&&&&&&&action&android:name="android.intent.action.USER_PRESENT"&/&&&
&&&&&&&&&action&android:name="com.dbjtech.waiqin.destroy"&/&
&&&&&/intent-filter&&&
&/receiver&&&
在onDestroy时:
@Override&&
public&void&onDestroy()&{&&
&&&&stopForeground(true);&&
&&&&Intent&intent&=&new&Intent("com.dbjtech.waiqin.destroy");&&
&&&&sendBroadcast(intent);&&
&&&&super.onDestroy();&&
在BootReceiver里
public&class&BootReceiver&extends&BroadcastReceiver&{&&
&&&&@Override&&
&&&&public&void&onReceive(Context&context,&Intent&intent)&{&&
&&&&&&&&if&(intent.getAction().equals("com.dbjtech.waiqin.destroy"))&{&&
&&&&&&&&&&&&
&&&&&&&&&&&&
&&&&&&&&&&&&&&&&startUploadService(context);&&
&&&&&&&&}&&
也可以直接在onDestroy()里startService
@Override&&
public&void&onDestroy()&{&&
&&&&&Intent&sevice&=&new&Intent(this,&MainService.class);&&
&&&&&this.startService(sevice);&&
&&&&super.onDestroy();&&
【结论】当使用类似口口管家等第三方应用或是在setting里-应用-强制停止时,APP进程可能就直接被干掉了,onDestroy方法都进不来,所以还是无法保证~.~
Application加上Persistent属性
看Android的文档知道,当进程长期不活动,或系统需要资源时,会自动清理门户,杀死一些Service,和不可见的Activity等所在的进程。但是如果某个进程不想被杀死(如数据缓存进程,或状态监控进程,或远程服务进程),可以这么做:
&application&&
&&&&android:name="com.test.Application"&&
&&&&android:allowBackup="true"&&
&&&&android:icon="@drawable/ic_launcher"&&
&&&&android:label="@string/app_name"&&
&&&&span&style="color:#ff0000;"&&android:persistent="true"&/span&&&
&&&&android:theme="@style/AppTheme"&&&&
&/application&&&
【结论】据说这个属性不能乱设置,不过设置后,的确发现优先级提高不少,或许是相当于系统级的进程,但是还是无法保证存活
监听系统广播判断Service状态
通过系统的一些广播,比如:手机重启、界面唤醒、应用状态改变等等监听并捕获到,然后判断我们的Service是否还存活,别忘记加权限啊。
&receiver&android:name="com.dbjtech.acbxt.waiqin.BootReceiver"&&&&
&&&&&intent-filter&&&
&&&&&&&&&action&android:name="android.intent.action.BOOT_COMPLETED"&/&&&
&&&&&&&&&action&android:name="android.intent.action.USER_PRESENT"&/&&&
&&&&&&&&&action&android:name="android.intent.action.PACKAGE_RESTARTED"&/&&&
&&&&&&&&&action&android:name="com.dbjtech.waiqin.destroy"&/&&&
&&&&&/intent-filter&&&
&/receiver&&&
BroadcastReceiver中:
@Override&&
public&void&onReceive(Context&context,&Intent&intent)&{&&
&&&&if&(Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction()))&{&&
&&&&&&&&System.out.println("手机开机了....");&&
&&&&&&&&startUploadService(context);&&
&&&&if&(Intent.ACTION_USER_PRESENT.equals(intent.getAction()))&{&&
&&&&&&&&&&&&startUploadService(context);&&
【结论】这也能算是一种措施,不过感觉监听多了会导致Service很混乱,带来诸多不便
将APK安装到/system/app,变身系统级应用
这个办法不推荐使用,因为如果你的APP如果是给用户使用的,那就不合适了,我是为了给测试的妹子来用,这个APP的目的也是很简单,打开后开启Service并且能保证一直在后台驻留,开机自启动。但是昨天发现如果
她的HuaWei手机长时间关闭, 再重新打开时,我们应用的Service不会自启动,貌似广播收不到了~一怒之下,打算搞成系统应用。
ROOT过的手机
1,把代码编写好后,打包导出apk,copy到手机SD卡根目录下。
2,手机连接eclipse,cmd: adb shell
3,切换root模式,输入:su & & (如果root过就不会有错误)
4,设置System为读写权限:mount&&o&remount&rw&/system (System默认为只读,无法写入,这一步很关键)
5,cd到sd卡跟目录下,确认是否有我们拷贝到sd卡根目录下的apk(一般都是 storage/sdcard0)
shell@android:/ # cd storage/sdcard0
6,最关键的一步,我们要把apk拷贝到 /System/app中:
发现copy命令无效~那么我们就用push把:
如果有错误:device not found,那么手机下载一个Root Explorer把,找到apk,copy到System/app下,通过这个APP要更容易一些。
7,system/app 确定拥有我们的APK后,重启手机把:
设置-应用程序管理,查看一下:
可以看到我们的APP已经无法卸载了,只能停用
这个时候,就算强制停止,或是关闭Service,重启手机后照样可以起来Service~!
系统级的APP,这样一些第三方的管家软件,就无法杀掉我们,除非自己把APP停用掉,或是强制停止(但是我的APP可以开机自启动)。
【结论】这种方式适合调试来用,并不算是一种解决办法,大家可以尝试在正在运行的界面:强制关闭搜狐视频的两个进程,重启手机,发现他又可以自启动,但是如果换成我们的APP,强制停止,进程挂了,再重启手机,无法自启动了~
大家一起研究,怎么样才能像上图搜狐视频一样,开启两个进程,相互监听,做到最大程度的存活,如果这个能实现了,那就和微信、360等一样的效果了。
转自:http://blog.csdn.net/mad1989/article/details/
阅读(...) 评论()

我要回帖

更多关于 android系统服务开发 的文章

 

随机推荐