您的位置:首页 > 移动开发 > Android开发

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);
startService(i1);Intent i2 = new Intent(MainActivity.this,Service2.class);
startService(i2);
项目运行之后,在通过一键清理之后就杀不死服务了,这就是微信和qq的双进程保护。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息