Android 杀不死的进程

最近和同事讨论微信杀死进程结束后,还能收到好友发来的微信这功能。以前一直用着,没有去研究这技术。最近项目提前完成,有了点空闲时间,就研究这技术。然后写了个demo,试着运行,发现OK了。在这给朋友分享下,可能有不够好的地方,欢迎大神们指出。

 

首先,正常下,当我们退出程序或手动杀死后,我们的程序就停止运行了。或者不退出在后台运行时,使用360加速球清理时,也会杀死我们的进程。个人理解360加速时,把不被添加信任的进程用一个for循环,在循环里一个个的kill。于是有了一种思路,在我们应用中开启两个进程,当一个进程被杀死时,另外一个进程启动被杀死的进程,相互守护。沿着这思路,开始撸代码。

 

1.创建两个Service:LocationServiceRemoteServices
LocationService代表主进程,RemoteServices代表守护进程。这里要实现RemoteServices是另外的进程需要在Androidmanifest中配置:
<service
    android:name=".RemoteServices"
    android:enabled="true"
    android:exported="true"
    android:process=".RemoteServices" />
接下来是要对这两个service相互绑定,相互监听对方的状态。两个进程中的通讯我们可以使用aidl,这里不对aidl细讲,不了解的朋友可以去查下。
创建一个ProcessIdle.aidl文件
// ProcessIdle.aidl

package inner;
interface ProcessIdle {

     String getProcessName();

}

 
这里只定义一个方法getProcessName(),用于获取进程名。接下来编写LocationServiceRemoteServices两个类。
RemoteServices
public class RemoteServices extends Service {
    MyBinder myBinder;
    MyConn myConn;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return myBinder;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        showWindow("RemoteServices======");
        Toast.makeText(this, "RemoteServices=======onStartCommand", Toast.LENGTH_SHORT).show();
        boolean isLocationServiceRunning = Util.isServiceRunning(this, "com.example.zonglijia.killapp.LocationService");

        if (!isLocationServiceRunning) {
            RemoteServices.this.startService(new Intent(RemoteServices.this, LocationService.class));
        }
        RemoteServices.this.bindService(new Intent(RemoteServices.this, LocationService.class), myConn, Context.BIND_IMPORTANT);
        return START_STICKY;
    }

    @Override
    public void onCreate() {
        Toast.makeText(this, "RemoteServices=======onCreate", Toast.LENGTH_SHORT).show();
        Log.i("RemoteServices", "onCreate");
        super.onCreate();
        if (myBinder == null)
            myBinder = new MyBinder();
        if (myConn == null) {
            myConn = new MyConn();
        }

//        showWindow("RemoteServices======");
    }

    class MyBinder extends ProcessIdle.Stub {

        @Override
        public String getProcessName() throws RemoteException {
            return "RemoteServices";
        }
    }

    class MyConn implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Toast.makeText(RemoteServices.this, "已连接本地服务", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Toast.makeText(RemoteServices.this, "断开连接本地服务", Toast.LENGTH_LONG).show();

            RemoteServices.this.startService(new Intent(RemoteServices.this, LocationService.class));
            RemoteServices.this.bindService(new Intent(RemoteServices.this, LocationService.class), myConn, Context.BIND_IMPORTANT);

        }
    }

    WindowManager mWM;
    TextView view;

    private void showWindow(String text) {
        mWM = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.width = WindowManager.LayoutParams.WRAP_CONTENT;
        params.format = PixelFormat.TRANSLUCENT;
        params.type = WindowManager.LayoutParams.TYPE_TOAST;
        params.setTitle("Toast");
        params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

//        view = LayoutInflater.from(this).inflate(R.layout.window_show, null);
//        TextView textView = (TextView) view.findViewById(R.id.text);
        view = new TextView(this);
        view.setText(text);
        view.setTextColor(Color.RED);
        mWM.addView(view, params);
    }

    @Override
    public void onDestroy() {
        Toast.makeText(this, "RemoteServices=======onDestroy", Toast.LENGTH_SHORT).show();
        Log.i("RemoteServices", "onDestroy");
        RemoteServices.this.startService(new Intent(RemoteServices.this, LocationService.class));
        RemoteServices.this.bindService(new Intent(RemoteServices.this, LocationService.class), myConn, Context.BIND_IMPORTANT);
        super.onDestroy();
    }
}
 
 
LocationService

public class LocationService extends Service {

    MyBinder myBinder;
    MyConn2 myConn2;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return myBinder;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        showWindow("LocationServices======");
        Toast.makeText(this, "LocationService=======onStartCommand", Toast.LENGTH_SHORT).show();
        boolean isRemoteServiceRunning = Util.isServiceRunning(this, "com.example.zonglijia.killapp.RemoteServices");

        if (!isRemoteServiceRunning) {
            LocationService.this.startService(new Intent(LocationService.this, RemoteServices.class));
        }
        LocationService.this.bindService(new Intent(LocationService.this, RemoteServices.class), myConn2, Context.BIND_IMPORTANT);
        return START_STICKY;
    }

    @Override
    public void onCreate() {
        Toast.makeText(this, "LocationService=======onCreate", Toast.LENGTH_SHORT).show();
        Log.i("LocationService", "onCreate");
        super.onCreate();
        if (myBinder == null)
            myBinder = new MyBinder();
        if (myConn2 == null) {
            myConn2 = new MyConn2();
        }


//        showWindow("LocationServices======");
    }

    class MyBinder extends ProcessIdle.Stub {

        @Override
        public String getProcessName() throws RemoteException {
            return "LocationProcess";
        }
    }

    class MyConn2 implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Toast.makeText(LocationService.this, "已连接远程服务", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Toast.makeText(LocationService.this, "断开连接远程服务", Toast.LENGTH_LONG).show();
            LocationService.this.startService(new Intent(LocationService.this, RemoteServices.class));
            LocationService.this.bindService(new Intent(LocationService.this, RemoteServices.class), myConn2, Context.BIND_IMPORTANT);
        }
    }

    WindowManager mWM;
    TextView view;

    private void showWindow(String text) {
        mWM = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.width = WindowManager.LayoutParams.WRAP_CONTENT;
        params.format = PixelFormat.TRANSLUCENT;
        params.type = WindowManager.LayoutParams.TYPE_TOAST;
        params.setTitle("Toast");
        params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

//        view = LayoutInflater.from(this).inflate(R.layout.window_show, null);
//        TextView textView = (TextView) view.findViewById(R.id.text);
        view = new TextView(this);
        view.setText(text);
        view.setTextColor(Color.RED);
        mWM.addView(view, params);
    }

    @Override
    public void onDestroy() {
        Log.i("LocationService", "onDestroy");
        Toast.makeText(this, "LocationService=======onDestroy", Toast.LENGTH_SHORT).show();
        LocationService.this.startService(new Intent(LocationService.this, RemoteServices.class));
        LocationService.this.bindService(new Intent(LocationService.this, RemoteServices.class), myConn2, Context.BIND_IMPORTANT);
        super.onDestroy();
    }
}
 
这两个类的代码内容几乎相同,其中的逻辑是先判断另一进程是否在运行,如果否就先启动,然后再进行绑定。当监听到另一进程断开时,就再次启动并绑定。就是下面的代码块
class MyConn2 implements ServiceConnection {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {

        Toast.makeText(LocationService.this, "已连接远程服务", Toast.LENGTH_LONG).show();

    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        Toast.makeText(LocationService.this, "断开连接远程服务", Toast.LENGTH_LONG).show();
        LocationService.this.startService(new Intent(LocationService.this, RemoteServices.class));
        LocationService.this.bindService(new Intent(LocationService.this, RemoteServices.class), myConn2, Context.BIND_IMPORTANT);

    }

}
 
好了,大致的思路就是这样,细节的处理代码就没再贴,需要的朋友可以在下面留言,可以发邮箱给你们。
 
运行测试后,在5.0以下的机型都测试成功,5.0以上机型除了在手动杀死进程时,测试失败,其它方式杀死都测试成功。对于在5.0以上的机型兼容,会再下一篇分享

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值