APP双进程伪守护,外部通知栏点击回到带数据的APP画面

1 双进程伪守护的原理

 开启2个服务分别在不同的进程里面,根据AIDL进行进程之间通信

本地服务跟远程服务互相绑定,当本地服务开启成功,开启远程服务,然后跟远程服务绑定。反之

当其中一个进程出现异常,另一个进程会马上把这个出现异常的进程重新启动。



2外部通知栏点击回到带数据的APP画面

参考地址http://write.blog.csdn.net/postedit


AIDL

package com.aidl;
interface ProecssXutils{
	void getString();
}


Service

package service;

import com.aidl.ProecssXutils;

import android.app.AlarmManager;

import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.widget.Toast;
import broadcasereciver.Notification;
import class_.Constans;

public class LocalService extends Service {
	private MyBilder mybilder;

	@Override
	public IBinder onBind(Intent intent) {
		if (mybilder == null) {
			mybilder = new MyBilder();
		}

		// TODO Auto-generated method stub
		return mybilder;
	}

	class MyBilder extends ProecssXutils.Stub {

		@Override
		public void getString() throws RemoteException {
			// TODO Auto-generated method stub
			Log.i("远程服务绑定", "----------------");
		}

	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// 服务启动成功
		// TODO Auto-generated method stub
		this.startService(new Intent(LocalService.this, RemoteService.class));// 当本地服务器启动成功,启动远程服务
		this.bindService(new Intent(LocalService.this, RemoteService.class), conn, Context.BIND_IMPORTANT);// 绑定远程服务

		AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);// 系统通知管理器
		Intent inttt = new Intent(LocalService.this, Notification.class);

		PendingIntent pendingIntent = PendingIntent.getBroadcast(LocalService.this, 0, inttt,
				PendingIntent.FLAG_UPDATE_CURRENT);
		// am.set(AlarmManager.ELAPSED_REALTIME,
		// SystemClock.currentThreadTimeMillis(), pendingIntent);
		am.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.currentThreadTimeMillis(), 10 * 1000, pendingIntent);//设置轮询时间10秒一次
		return START_STICKY;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();

	}

	private ServiceConnection conn = new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// 连接成功
			Toast.makeText(LocalService.this, "本地服务启动", Toast.LENGTH_SHORT).show();

		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// 连接异常
			LocalService.this.startService(new Intent(LocalService.this, RemoteService.class));
			LocalService.this.bindService(new Intent(LocalService.this, RemoteService.class), conn,
					Context.BIND_IMPORTANT);
		}
	};
}

package service;

import com.aidl.ProecssXutils;

import android.app.AlarmManager;

import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.widget.Toast;
import broadcasereciver.Notification;
import service.LocalService.MyBilder;

public class RemoteService extends Service {
	private MyBilder mybilder;

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

	class MyBilder extends ProecssXutils.Stub {

		@Override
		public void getString() throws RemoteException {
			// TODO Auto-generated method stub
			Log.i("远程服务绑定", "----------------");
		}

	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		this.startService(new Intent(RemoteService.this, LocalService.class));
		this.bindService(new Intent(RemoteService.this, LocalService.class), conn, Context.BIND_IMPORTANT);

		AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
		Intent inttt = new Intent(RemoteService.this, Notification.class);
	
		PendingIntent pendingIntent = PendingIntent.getBroadcast(RemoteService.this, 0, inttt,
				PendingIntent.FLAG_UPDATE_CURRENT);
		am.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.currentThreadTimeMillis(), 10 * 1000, pendingIntent);//设置轮询时间10秒一次
		return START_STICKY;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		if (mybilder == null) {
			mybilder = new MyBilder();
		}

	}

	private ServiceConnection conn = new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// 连接成功
			Toast.makeText(RemoteService.this, "远程服务启动", Toast.LENGTH_SHORT).show();

		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// 连接异常
			RemoteService.this.startService(new Intent(RemoteService.this, LocalService.class));
			RemoteService.this.bindService(new Intent(RemoteService.this, LocalService.class), conn,
					Context.BIND_IMPORTANT);
		}
	};
}



BroadcastReceiver


package broadcasereciver;

import android.R;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

public class Notification extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub

		Log.i("Notification", "------------------");
		Intent in = new Intent(context, ToNotification.class);
		PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, in, PendingIntent.FLAG_UPDATE_CURRENT);//当存在时,先把原来的取消,然后创建一个新的,在AlarmManager服务时,修改一个闹铃,用的比较笨的的方法,先取消,然后重新注册,其实加上这个参数就行了
		NotificationCompat.Builder builder = new NotificationCompat.Builder(context);//通知栏设置
		builder.setContentTitle("服务开启").setContentText("text").setTicker("Ticker")
				.setSmallIcon(R.drawable.alert_dark_frame).setContentIntent(pendingIntent).build();
		
		//通过NotificationManager对象的notify方法来执行一行notification
		NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
		manager.notify(2, builder.build());//执行通知栏

	}

}

package broadcasereciver;

import activity.MainActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import class_.Constans;
import class_.SystemUtils;

public class ToNotification extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub

		if(SystemUtils.isAppAlive(context, "com.xcl.demo")){//判断进程是否存在
			
			Intent ints= new Intent(context,MainActivity.class);
			ints.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			Bundle bun = new Bundle();
			bun.putString("bundle", "进程存在");
			ints.putExtra(Constans.FALG, bun);
			context.startActivity(ints);
		}else{
			Intent intss = context.getPackageManager().getLaunchIntentForPackage("com.xcl.demo");//不存在重新启动APP
			intss.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
			Bundle bun = new Bundle();
			bun.putString("bundle", "进程不存在");
			intss.putExtra(Constans.FALG, bun);
			context.startActivity(intss);
		}
	}

}


Activity

package activity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
import class_.Constans;
import service.LocalService;

public class Login_ extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);

		final TextView tv = new TextView(this);
		tv.setText("登陆界面");
		setContentView(tv);
		new Handler().postDelayed(new Runnable() {

			@Override
			public void run() {
				Intent it = new Intent(Login_.this,MainActivity.class);

				if (getIntent().getBundleExtra(Constans.FALG) != null) {
					tv.setText(getIntent().getBundleExtra(Constans.FALG).getString("bundle"));
					it.putExtra(Constans.FALG, getIntent().getBundleExtra(Constans.FALG));
				}
				startActivity(it);
				finish();

			}
		}, 3000);
	}

}

package activity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
import class_.Constans;
import service.LocalService;
import service.RemoteService;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		TextView te = new TextView(this);
		setContentView(te);
		
		this.startService(new Intent(this,LocalService.class));//开启本地服务
		this.startService(new Intent(this,RemoteService.class));//开启远程服务
	
		if (getIntent().getBundleExtra(Constans.FALG) != null) {//当进程存在的时候  Bundler会存在值  参考ToNotification类
			te.setText(getIntent().getBundleExtra(Constans.FALG).getString("bundle"));
		} else {
			te.setText("空值");//进程不存在 重启APP Bundler是NULL  
		
		}
	
	}

}


工具类

package class_;

public class Constans {
		public static final String FALG="bundle";//全局变量
}


package class_;

import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import java.util.List;



/**
 * Created by liangzili on 15/8/3.
 */
public class SystemUtils {
    /**
     * 判断应用是否已经启动
     * @param context 一个context
     * @param packageName 要判断应用的包名
     * @return boolean
     */
    public static boolean isAppAlive(Context context, String packageName){
        ActivityManager activityManager =
                (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> processInfos
                = activityManager.getRunningAppProcesses();
        for(int i = 0; i < processInfos.size(); i++){
            if(processInfos.get(i).processName.equals(packageName)){
                Log.i("NotificationLaunch",
                        String.format("the %s is running, isAppAlive return true", packageName));
                return true;
            }
        }
        Log.i("NotificationLaunch",
                String.format("the %s is not running, isAppAlive return false", packageName));
        return false;
    }

   
}



AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xcl.demo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity android:name="activity.Login_" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" >
                </action>

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
<activity android:name="activity.MainActivity"></activity>
        <service
            android:name="service.LocalService"
            android:process=":remote" >
        </service>
        <service
            android:name="service.RemoteService"
            android:process=":push" >
        </service>

        <receiver
            android:name="broadcasereciver.Notification"
            android:process=":push" >
        </receiver>
        <receiver
            android:name="broadcasereciver.ToNotification"
            android:process=":push" >
        </receiver>
    </application>

</manifest>


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值