Android创建杀不死的服务
2015-09-15 09:55
627 查看
杀不死的Service,理论上是很流氓的行为,现在不流氓不行啊,只要用户感觉不出来就OK了,我所知道的有两种方法:1,创建两个Service,当一个Service销毁时,启动另一个Service!2,通过AlarmManager定时去发送广播,然后在广播里面启动Service现在重点说一说第二种:AlarmManager是什么东西?顾名思义,就是“提醒”,是Android中常用的一种系统级别的提示服务,在特定的时刻为我们广播一个指定的Intent。简单的说就是我们设定一个时间,然后在该时间到来时,AlarmManager为我们广播一个我们设定的Intent,通常我们使用 PendingIntent,PendingIntent可以理解为Intent的封装包,简单的说就是在Intent上在加个指定的动作。在使用Intent的时候,我们还需要在执行startActivity、startService或sendBroadcast才能使Intent有用。而PendingIntent的话就是将这个动作包含在内了。那么,我们要创建一个PendingIntent,怎么创建?如果是通过启动服务来实现闹钟提示的话,PendingIntent对象的获取就应该采用Pending.getService(Context c,int i,Intent intent,int j)方法;如果是通过广播来实现闹钟提示的话,PendingIntent对象的获取就应该采用 PendingIntent.getBroadcast(Context c,int i,Intent intent,int j)方法;如果是采用Activity的方式来实现闹钟提示的话,PendingIntent对象的获取就应该采用 PendingIntent.getActivity(Context c,int i,Intent intent,int j)方法,所以对应的是什么就要get对应的intent,我们这里是用到广播,所以我们要getBroadcast,
AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE); //包装需要执行Service的Intent // Intent intent = new Intent(this, this.getClass()); // PendingIntent pendingIntent = PendingIntent.getService(this, 0, // intent, PendingIntent.FLAG_UPDATE_CURRENT); long triggerAtTime = SystemClock.elapsedRealtime(); Intent i = new Intent(this, AlarmBrocast.class); PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0); manager.setRepeating(AlarmManager.ELAPSED_REALTIME, triggerAtTime, 60 * 1000, pi);
manager.setRepeating(AlarmManager.ELAPSED_REALTIME, triggerAtTime, 60 * 1000,pi); 是第一个参数表示闹钟类型,第二个参数表示闹钟首次执行时间,第三个参数表示闹钟两次执行的间隔时间,第三个参数表示闹钟响应动作。动作就是AlarmBrocast!这样就会每隔一分钟去发送一次广播,
/** * Created by Administrator on 2015/9/8. */ public class AlarmBrocast extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Intent i = new Intent(); i.setClass(context, LocService.class); context.startService(i); } }广播来启动Service,就是每隔一分钟服务都会启动一次,因为是startService,所以重复启动他只会走onstart方法;这样杀掉也会被AlarmManager 和广播拉起来!既然有人说我的一杀就死,那个是根据自己的应用需求来的,那我现在说说第一种,创建两个服务service1和service2,当其中一个service被杀死的情况下,立即拉起第二个service,两个服务属于两个进程。所以我们还要进程间通讯。要知道service到底有没有被杀死,所以我们要写一个判断服务有没有被杀死的方法:
/** * 判断进程是否运行 * @return */ public static boolean isProessRunning(Context context, String proessName) { boolean isRunning = false; ActivityManager am = (ActivityManager) context .getSystemService(Context.ACTIVITY_SERVICE); List<RunningAppProcessInfo> lists = am.getRunningAppProcesses(); for (RunningAppProcessInfo info : lists) { if (info.processName.equals(proessName)) { isRunning = true; } } return isRunning; }把两个服务放在不同的进程就要在mainfest文件里面注册的时候说明一下属性,
<service android:name="com.service.Service1" android:enabled="true" android:process=":service1"></service> <service android:name="com.service.Service2" android:enabled="true" android:process=":service2"></service>在注册之后,service1属于在service1进程,service2属于在service2进程,那么进程间通讯需要aidl,所以我们要声明一个aidl文件,
package com.service.demo; interface StrongService{ void startService(); void stopService(); }然后创建服务service1
package com.service.demo; import java.util.List; import android.app.ActivityManager; import android.app.ActivityManager.RunningAppProcessInfo; import android.app.Service; import android.app.ActivityManager.RunningServiceInfo; import android.content.ComponentCallbacks; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.res.Configuration; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import android.widget.Toast; /** * * @author * */ public class Service1 extends Service { private String TAG = getClass().getName(); // 用于判断进程是否运行 private String Process_Name = "com.example.servicetest2:service2"; /** *启动Service2 */ private StrongService startS2 = new StrongService.Stub() { @Override public void stopService() throws RemoteException { Intent i = new Intent(getBaseContext(), Service2.class); getBaseContext().stopService(i); } @Override public void startService() throws RemoteException { Intent i = new Intent(getBaseContext(), Service2.class); getBaseContext().startService(i); } }; @Override public void onTrimMemory(int level){ Toast.makeText(getBaseContext(), "Service1 onTrimMemory..."+level, Toast.LENGTH_SHORT) .show(); keepService2();//保持Service2一直运行 } @Override public void onCreate() { Toast.makeText(Service1.this, "Service1 onCreate...", Toast.LENGTH_SHORT) .show(); keepService2(); } /** * 判断Service2是否还在运行,如果不是则启动Service2 */ private void keepService2(){ boolean isRun = Utils.isProessRunning(Service1.this, Process_Name); if (isRun == false) { try { Toast.makeText(getBaseContext(), "重新启动 Service2", Toast.LENGTH_SHORT).show(); startS2.startService(); } catch (RemoteException e) { e.printStackTrace(); } } } @Override public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; } @Override public IBinder onBind(Intent intent) { return (IBinder) startS2; } }创建service2
package com.service.demo; import java.util.List; import android.app.ActivityManager; import android.app.ActivityManager.RunningAppProcessInfo; import android.app.Service; import android.app.ActivityManager.RunningServiceInfo; import android.content.ComponentCallbacks; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.res.Configuration; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import android.widget.Toast; /** * * @author * */ public class Service1 extends Service { private String TAG = getClass().getName(); // 用于判断进程是否运行 private String Process_Name = "com.example.servicetest2:service2"; /** *启动Service2 */ private StrongService startS2 = new StrongService.Stub() { @Override public void stopService() throws RemoteException { Intent i = new Intent(getBaseContext(), Service2.class); getBaseContext().stopService(i); } @Override public void startService() throws RemoteException { Intent i = new Intent(getBaseContext(), Service2.class); getBaseContext().startService(i); } }; @Override public void onTrimMemory(int level){ Toast.makeText(getBaseContext(), "Service1 onTrimMemory..."+level, Toast.LENGTH_SHORT) .show(); keepService2();//保持Service2一直运行 } @Override public void onCreate() { Toast.makeText(Service1.this, "Service1 onCreate...", Toast.LENGTH_SHORT) .show(); keepService2(); } /** * 判断Service2是否还在运行,如果不是则启动Service2 */ private void keepService2(){ boolean isRun = Utils.isProessRunning(Service1.this, Process_Name); if (isRun == false) { try { Toast.makeText(getBaseContext(), "重新启动 Service2", Toast.LENGTH_SHORT).show(); startS2.startService(); } catch (RemoteException e) { e.printStackTrace(); } } } @Override public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; } @Override public IBinder onBind(Intent intent) { return (IBinder) startS2; } }然后在点击的时候启动两个服务
Intent i1 = new Intent(MainActivity.this,Service1.class);项目运行之后,在通过一键清理之后就杀不死服务了,这就是微信和qq的双进程保护。
startService(i1);Intent i2 = new Intent(MainActivity.this,Service2.class);
startService(i2);
相关文章推荐
- 利用IE收听“广播”
- C#使用timer实现的简单闹钟程序
- Android广播接收机制详细介绍(附短信接收实现)
- C++实现闹钟程序的方法
- C#实现闹钟AlarmClock实例代码
- Jquery实现仿腾讯微博发表广播
- Android实现静态广播监听器的方法
- Android中的广播、服务、数据库、通知、包等术语的原理和介绍(图解)
- Android中的广播(BroadCast)详细介绍
- Android中的广播和广播接收器代码实例
- Android开发之广播机制浅析
- 一些Manager类整理
- 广播
- 网络广播风暴的几种原因
- 【原理总结】DHCP数据包分析
- 广播 BroadCastReceiver
- Envivio发布4Caster™ 广播3500实况H.264编码器
- BroadcastReceiver应用详解
- Android广播机制分析
- Android受限广播保护机制