Android APP进程保护,在APP进程异常崩溃后能够重启

来源:互联网 发布:金十数据 更新 编辑:程序博客网 时间:2024/04/28 16:35

这个地方借鉴了前一段时间吵得热闹的 蜻蜓FM app的问题,蜻蜓FM app在内部做了5个进程,并且这5个进程互相保护,不被安全APP杀死.

大致的原理: 5个进程不断查询其他某一个进程的运行状况,当有所监查的进程不存在了,无论是因为安全软件kill了还是因为程序本身奔溃了,就将其重新启动,但是如果监控的服务和被监控的服务如果在同一个进程,那就无法实现,因为被监控的进程crash了,意味着监控的进程也crash了,那么两者都奔溃了,就不可能重启了,所以监控和被监控的两个对象必须不能够在同一个进程中.


下面做一个简单测试工程:

<1> : 工程树如下:


<2> : 工程文件内容如下:

IProtectServiceA.aidl
// IProtectServiceA.aidlpackage org.durian.durianprotectprocess;// Declare any non-default types here with import statementsinterface IProtectServiceA {    /**     * Demonstrates some basic types that you can use as parameters     * and return values in AIDL.     */    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,            double aDouble, String aString);    void startServiceB();    void stopServiceB();}

IProtectServiceB.aidl
// IProtectServiceB.aidlpackage org.durian.durianprotectprocess;// Declare any non-default types here with import statementsinterface IProtectServiceB {    /**     * Demonstrates some basic types that you can use as parameters     * and return values in AIDL.     */    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,            double aDouble, String aString);    void startServiceA();    void stopServiceA();}


ProtectServiceA.java

package org.durian.durianprotectprocess.org.durian.protectservice;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import org.durian.durianprotectprocess.IProtectServiceA;import static org.durian.durianprotectprocess.IProtectServiceA.*;public class ProtectServiceA extends Service {    private final static String TAG="ProtectServiceA";    public ProtectServiceA() {    }    @Override    public IBinder onBind(Intent intent) {        // TODO: Return the communication channel to the service.        throw new UnsupportedOperationException("Not yet implemented");    }    private IProtectServiceA mProtA=new Stub(){        @Override        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {        }        @Override        public void startServiceB() throws RemoteException {            Intent intent=new Intent(ProtectServiceA.this,ProtectServiceB.class);            ProtectServiceA.this.startService(intent);        }        @Override        public void stopServiceB() throws RemoteException {            Intent intent=new Intent(ProtectServiceA.this,ProtectServiceB.class);            ProtectServiceA.this.stopService(intent);        }    };    @Override    public void onCreate() {        super.onCreate();        new Thread() {            public void run() {                while (true) {                    boolean isRun = Utils.isProessRunning(ProtectServiceA.this, Utils.DURIAN_PROCESS_B);                    if (isRun==false) {                        try {                            mProtA.startServiceB();                        } catch (RemoteException e) {                            e.printStackTrace();                        }                    }                }            };        }.start();    }}

ProtectServiceB.java


package org.durian.durianprotectprocess.org.durian.protectservice;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import org.durian.durianprotectprocess.IProtectServiceB;public class ProtectServiceB extends Service {    public ProtectServiceB() {    }    @Override    public IBinder onBind(Intent intent) {        // TODO: Return the communication channel to the service.        throw new UnsupportedOperationException("Not yet implemented");    }    private IProtectServiceB mProtB=new IProtectServiceB.Stub(){        @Override        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {        }        @Override        public void startServiceA() throws RemoteException {            Intent intent=new Intent(ProtectServiceB.this,ProtectServiceA.class);            ProtectServiceB.this.startService(intent);        }        @Override        public void stopServiceA() throws RemoteException {            Intent intent=new Intent(ProtectServiceB.this,ProtectServiceA.class);            ProtectServiceB.this.stopService(intent);        }    };    @Override    public void onCreate() {        super.onCreate();        new Thread() {            public void run() {                while (true) {                    boolean isRun = Utils.isProessRunning(ProtectServiceB.this, Utils.DURIAN_PROCESS_A);                    if (isRun==false) {                        try {                            mProtB.startServiceA();                        } catch (RemoteException e) {                            e.printStackTrace();                        }                    }                }            };        }.start();    }}


Utils.java
package org.durian.durianprotectprocess.org.durian.protectservice;import android.app.ActivityManager;import android.content.Context;import android.util.Log;import java.util.List;/** * Created by zhibao.liu on 2016/1/7. */public class Utils {    public final static String DURIAN_PROCESS_A="org.durian.protect.a";    public final static String DURIAN_PROCESS_B="org.durian.protect.b";    //服务是否运行    public boolean isServiceRunning(Context context, String serviceName) {        boolean isRunning = false;        ActivityManager am = (ActivityManager) context                .getSystemService(Context.ACTIVITY_SERVICE);        List<ActivityManager.RunningServiceInfo> lists = am.getRunningServices(30);        for (ActivityManager.RunningServiceInfo info : lists) {// 获取运行服务再启动            if (info.service.getClassName().equals(serviceName)) {                Log.i("Service1进程", "" + info.service.getClassName());                isRunning = true;            }        }        return isRunning;    }    // 进程是否运行    public static boolean isProessRunning(Context context, String proessName) {        boolean isRunning = false;        ActivityManager am = (ActivityManager) context                .getSystemService(Context.ACTIVITY_SERVICE);        List<ActivityManager.RunningAppProcessInfo> lists = am.getRunningAppProcesses();        for (ActivityManager.RunningAppProcessInfo info : lists) {            if (info.processName.equals(proessName)) {                //Log.i("Service1进程", "" + info.processName);                isRunning = true;            }        }        return isRunning;    }}

DurianMainActivity.java
package org.durian.durianprotectprocess;import android.content.Intent;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.Button;import org.durian.durianprotectprocess.org.durian.protectservice.ProtectServiceA;import org.durian.durianprotectprocess.org.durian.protectservice.ProtectServiceB;public class DurianMainActivity extends ActionBarActivity {    private Button mButton;    private Intent mService;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.durian_main);        mButton=(Button)findViewById(R.id.button);        mButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mService=new Intent(DurianMainActivity.this, ProtectServiceA.class);                DurianMainActivity.this.startService(mService);                mService=new Intent(DurianMainActivity.this, ProtectServiceB.class);                DurianMainActivity.this.startService(mService);            }        });    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.menu_durian_main, menu);        return true;    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        // Handle action bar item clicks here. The action bar will        // automatically handle clicks on the Home/Up button, so long        // as you specify a parent activity in AndroidManifest.xml.        int id = item.getItemId();        //noinspection SimplifiableIfStatement        if (id == R.id.action_settings) {            return true;        }        return super.onOptionsItemSelected(item);    }}

布局:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <Button        android:id="@+id/button"        android:text="start service"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /></LinearLayout>



<3> : 运行以后 :

查看系统进程:

> adb shell

> su

> ps


杀死其中一个进程:

> kill 进程ID

比如杀死A 进程 :

> kill 18313

然后在ps一次,因为不是每隔一段时间检查的,只要一旦检查到就重启了.

注意看这时a进程的id号,对比上面变化了,说明服务被重启了.



0 0
原创粉丝点击