双服务+时间广播和屏幕广播实现Android App保活
来源:互联网 发布:ubuntu 12.04 源 编辑:程序博客网 时间:2024/05/02 08:23
双服务+时间广播和屏幕广播实现Android App保活
最近做项目的时候,需要app保持常在的状态来接受服务器的推送消息,所以实现了app的保活。虽然实现了程序的保活,实际上是用户是可以手动杀死的,如果用户没有手动杀死app,那么系统在内存紧张的时候可以保证app存活在手机当中,既有效的保护了APP的正常运行,也能够让用户可控。
实现的原理是开启两个服务来相互拉取,保证app正常存活。通过监听系统的时间变化广播来和屏幕关闭以及解锁的广播来动态检查服务是不是存活,如果没有存活就拉起服务。
首先我们需要开启两个服务MyServiceOne和MyServiceTwo。代码如下:
MyServiceOne
public class MyServiceOne extends Service { public final static String TAG = "myservice1"; public MyServiceOne() { } @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG, "onStartCommand"); startServiceTwo(); //如果这个Service被系统Kill了或者app被Kill了,Service还能自动重启。 return START_REDELIVER_INTENT; } @Override public void onCreate() { super.onCreate(); Log.e(TAG, "服务创建了"); startServiceTwo(); } @Override public void onDestroy() { super.onDestroy(); Log.e(TAG, "服务销毁了"); startServiceTwo(); } private void startServiceTwo() { //myservice2是MyServiceTwo的名字,我们会在manifest中定义,这里必须和manifest中定义的一样 boolean b = ServiceMangerUtils.isServiceWorked(MyServiceOne.this, "myservice2"); if(!b) { Intent service = new Intent(MyServiceOne.this, MyServiceTwo.class); startService(service); Log.e(TAG, "Start ServiceTwo"); } }}
MyServiceTwo
public class MyServiceTwo extends Service { public final static String TAG = "myservice2"; public MyServiceTwo() { } @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG, "onStartCommand"); startServiceOne(); //如果这个Service被系统Kill了或者app被Kill了,Service还能自动重启。 return START_REDELIVER_INTENT; } @Override public void onCreate() { super.onCreate(); Log.e(TAG, "服务创建了"); startServiceOne(); } @Override public void onDestroy() { super.onDestroy(); Log.e(TAG, "服务销毁了"); startServiceOne(); } /** * 检查服务是否存在,不存在唤起 */ private void startServiceOne() { boolean b = ServiceMangerUtils.isServiceWorked(MyServiceTwo.this, "myservice1"); if (!b) { Intent service = new Intent(MyServiceTwo.this, MyServiceOne.class); startService(service); Log.e(TAG, "start ServiceOne"); } }}
我们需要在manifest清单文件中注册我们的服务:
<service android:name=".service.MyServiceOne" android:persistent="true" android:process=":remote"> <!--intent-filter android:priority="1000" 将服务的优先级设置为最高1000 --> <intent-filter android:priority="1000"> <!--这里定义服务的名字--> <action android:name="myservice1" /> </intent-filter> </service> <service android:name=".service.MyServiceTwo" android:persistent="true" android:process=":remote"> <intent-filter android:priority="1000"> <action android:name="myservice2" /> </intent-filter> </service>
创建接收系统时间广播和屏幕广播的接收广播,时间广播在屏幕关闭以后可能不会再接收到,所以需要在屏幕解锁时检查服务的状态,保证APP在屏幕解锁时就能启动。
package liuxiaozhu.com.appkeepalive.brodcast;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.util.Log;import liuxiaozhu.com.appkeepalive.MainActivity;import liuxiaozhu.com.appkeepalive.MyAppliction;import liuxiaozhu.com.appkeepalive.ServiceMangerUtils;import liuxiaozhu.com.appkeepalive.service.MyServiceOne;/** * Created by liuxiaozhu on 2017/5/11. * All Rights Reserved by * 用来监听手机时间广播(在appliytion里开启广播),每一分钟系统会发送一次 * 该广播只需要拉起service1 */public class MyBroadcast extends BroadcastReceiver { private boolean isServiceRunning = false; @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) {//如果广播是每分钟发送一次的时间广播 Log.e("timeBroad", "时间变化了"); isServiceRunning = ServiceMangerUtils.isServiceWorked(MyAppliction.getmContext(), "myservice1"); if (!isServiceRunning) { Intent i = new Intent(context, MyServiceOne.class); context.startService(i); } } if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { Log.e("timeBroad", "屏幕解锁了"); isServiceRunning = ServiceMangerUtils.isServiceWorked(MyAppliction.getmContext(), "myservice1"); if (!isServiceRunning) { Intent i = new Intent(context, MyServiceOne.class); context.startService(i); } } if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { Log.e("timeBroad", "屏幕关闭了"); isServiceRunning = ServiceMangerUtils.isServiceWorked(MyAppliction.getmContext(), "myservice1"); if (!isServiceRunning) { Intent i = new Intent(context, MyServiceOne.class); context.startService(i); } } }}
自定义MyAppliction继承Appliction,在app启动的时候启动服务,注册广播,时间广播和屏幕广播是系统广播,我们不能在清单里注册只能在代码中注册。
/** * Created by liuxiaozhu on 2017/7/12. * All Rights Reserved by YiZu */public class MyAppliction extends Application { private static Context mContext; @Override public void onCreate() { super.onCreate(); mContext = getApplicationContext(); //开启系统时间广播(动态注册,不能静态注册) //部分机型会屏蔽时间广播 IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_TIME_TICK);//系统时间,每分钟发送一次 intentFilter.addAction(Intent.ACTION_SCREEN_ON);//屏幕打开(解锁), intentFilter.addAction(Intent.ACTION_SCREEN_OFF);//屏幕关闭 MyBroadcast myBroadcast = new MyBroadcast(); registerReceiver(myBroadcast, intentFilter); startMyService(); } public static Context getmContext() { return mContext; } /** * 开启双服务 */ private void startMyService() { Intent serviceOne = new Intent(); serviceOne.setClass(this, MyServiceOne.class); startService(serviceOne); }}
判断服务是否存货的工具类。
/** * Created by liuxiaozhu on 2017/7/12. * All Rights Reserved by YiZu */public class ServiceMangerUtils { /** * 判断服务是否运行 * * @param context * @param serviceName * @return */ public static boolean isServiceWorked(Context context, String serviceName) { ActivityManager myManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); //获取当前所有服务 ArrayList<ActivityManager.RunningServiceInfo> runningService = (ArrayList<ActivityManager.RunningServiceInfo>) myManager.getRunningServices(Integer.MAX_VALUE); for (int i = 0; i < runningService.size(); i++) { if (runningService.get(i).service.getClassName().equals(serviceName)) { return true; } } return false; }}
到这里我们的app就可以实现保活了,很好用但是不是太流氓,仅供大家学习,如果没有需要不建议使用。
源码已上传到GitHub,传送门地址
阅读全文
0 0
- 双服务+时间广播和屏幕广播实现Android App保活
- android广播和服务
- Android广播和服务
- Android之 广播和服务
- Android定时广播和定时服务两种实现方式
- Android定时广播和定时服务两种实现方式
- Android 屏幕事件广播
- Android中“强制停止”和广播保活的一个小坑
- android自定义广播实现app完全退出
- android自定义广播实现app完全退出
- android自定义广播实现app完全退出
- Android自定义广播实现app完全退出
- Android-服务与广播实现简单电话录音
- Android广播和广播接收者
- Android应用开发-广播和服务
- Android中的广播接收者和服务
- Android 广播与服务
- Android 广播与服务
- jqGrid参数列表
- 关于NLPIR应用在KETTLE中的探索
- Sqlserver2008相关配置问题
- Kettle资源库采用SQLserver数据库需要注意的点
- windows server2012部署Cognos问题小结
- 双服务+时间广播和屏幕广播实现Android App保活
- Cognos由于JAVA_HOME冲突引起的错误假象
- Word标题无法降级别
- 5.0系统录音权限
- SSAS建模遇到的问题集锦
- Oracle 11g导入导出命令
- Session是怎么实现的?存储在哪里?
- SSIS连接Oracle遇到的问题
- HTML img图片出现下边距的解决方法