Android进程保活全攻略(中)

2024-06-24 05:38

本文主要是介绍Android进程保活全攻略(中),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在上一篇博客Android进程保活全攻略(上)中介绍了进程保活的背景和一些方法的思路和实现方式,本篇博客我将承接上篇博客,继续进行介绍。

9) 1像素悬浮层
**思路:**1像素悬浮层是传说的QQ黑科技,监控手机锁屏解锁事件,在屏幕锁屏时启动1个像素的 Activity,在用户解锁时将 Activity 销毁掉。注意该 Activity 需设计成用户无感知。通过该方案,可以使进程的优先级在屏幕锁屏时间由4提升为最高优先级1。
保活强度:
前台进程,跟前台服务差不多。需要权限,不敌force-stop
实现代码:
首先定义 Activity,并设置 Activity 的大小为1像素:

public class MainActivity extendsAppCompatActivity {private static final StringTAG="keeplive";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//setContentView(R.layout.activity_main);Window window = getWindow();window.setGravity(Gravity.LEFT|Gravity.TOP);WindowManager.LayoutParams params = window.getAttributes();params.x=0;params.y=0;params.height=1;params.width=1;window.setAttributes(params);}
}

其次,从 AndroidManifest 中通过如下属性,排除 Activity 在 RecentTask 中的显示:

<activity
    android:name=".KeepAliveActivity"android:excludeFromRecents="true"android:exported="false"android:finishOnTaskLaunch="false"android:launchMode="singleInstance"android:process=":live"android:theme="@style/LiveActivityStyle">
</activity>

最后,控制 Activity 为透明:

<stylename="LiveActivityStyle"><itemname="android:windowBackground">@android:color/transparent</item><itemname="android:windowFrame">@null</item><itemname="android:windowNoTitle">true</item><itemname="android:windowIsFloating">true</item><itemname="android:windowIsTranslucent">true</item><itemname="android:windowContentOverlay">@null</item><itemname="android:windowAnimationStyle">@null</item><itemname="android:windowDisablePreview">true</item><itemname="android:windowNoDisplay">true</item>
</style>

Activity 启动与销毁时机的控制:

public class KeepLiveReceiver extendsBroadcastReceiver {privateContextmContext;@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (action.equals(Intent.ACTION_SCREEN_OFF)) {KeepLiveManeger.getInstance(mContext).startKeepLiveActivity();} else if (action.equals(Intent.ACTION_USER_PRESENT)) {KeepLiveManeger.getInstance(mContext).destroyKeepLiveActivity();}KeepLiveManeger.getInstance(mContext).startKeepLiveService();}
}

10) 应用间互相拉起
**思路:**app之间知道包名就可以相互唤醒了,比如你杀了我qq,只要微信还在就能确保随时唤醒qq。还有百度全系app都通过bdshare实现互拉互保,自定义一个广播,定时发,其他app收广播自起等

11) 心跳唤醒
思路:微信保活技术,依赖系统特性:长连接网络回包机制
保活强度:不敌force-stop,需要网络,API level >= 23的doze模式会关闭所有的网络
代码实现:

public class HeartbeatService extends Service implements Runnable {private Thread mThread;public int count = 0;private boolean isTip = true;private static String mRestMsg;private static String KEY_REST_MSG = "KEY_REST_MSG";@Overridepublic void run() {while (true) {try {if (count > 1) {count = 1;if (isTip) {//判断应用是否在运行ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);List<RunningTaskInfo> list = am.getRunningTasks(3);for (RunningTaskInfo info : list) {if (info.topActivity.getPackageName().equals("org.yhn.demo")) {//通知应用,显示提示“连接不到服务器”Intent intent = new Intent("org.yhn.demo");intent.putExtra("msg", true);sendBroadcast(intent);break;}}isTip = false;}}if (mRestMsg != "" && mRestMsg != null) {//向服务器发送心跳包sendHeartbeatPackage(mRestMsg);count += 1;}Thread.sleep(1000 * 3);} catch (InterruptedException e) {e.printStackTrace();}}}private void sendHeartbeatPackage(String msg) {HttpGet httpGet = new HttpGet(msg);DefaultHttpClient httpClient = new DefaultHttpClient();// 发送请求HttpResponse httpResponse = null;try {httpResponse = httpClient.execute(httpGet);} catch (Exception e) {e.printStackTrace();}if (httpResponse == null) {return;}// 处理返回结果final int responseCode = httpResponse.getStatusLine().getStatusCode();if (responseCode == HttpStatus.SC_OK) {//只要服务器有回应就OKcount = 0;isTip = true;} else {Log.i("@qi", "responseCode " + responseCode);}}@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();}@Overridepublic void onDestroy() {super.onDestroy();}public void onStart(Intent intent, int startId) {Log.i("@qi", "service onStart");//从本地读取服务器的URL,如果没有就用传进来的URLmRestMsg = getRestMsg();if (mRestMsg == null || mRestMsg == "") {mRestMsg = intent.getExtras().getString("url");}setRestMsg(mRestMsg);mThread = new Thread(this);mThread.start();count = 0;super.onStart(intent, startId);}public String getRestMsg() {SharedPreferences prefer = getSharedPreferences("settings.data", Context.MODE_PRIVATE);return prefer.getString(KEY_REST_MSG, "");}public void setRestMsg(String restMsg) {SharedPreferences prefer = getSharedPreferences("settings.data", Context.MODE_PRIVATE);SharedPreferences.Editor editor = prefer.edit();editor.putString(KEY_REST_MSG, restMsg);editor.commit();}}

最后别忘了注册Server和GET_TASKS

<service
    android:name=".demo.HeartbeatService"android:label="QServer"android:persistent="true" ><intent-filter><action android:name="HeartbeatService" /></intent-filter>
</service>
<uses-permission android:name="android.permission.GET_TASKS" /><uses-permission android:name="android.permission.GET_TASKS" />

12) Native进程拉起
思路:开启native子进程,定时发intent
保活强度:单杀可以杀死,force close 5.0以上无效,5.0以下部分手机无效,第三方软件下无效,且无法保证实时常驻
实现代码:
首先开启一个c进程,将需要保活的service名字传递进去

private static void start(Context context, Class<?> daemonClazzName, int interval) {String cmd = context.getDir(BIN_DIR_NAME, Context.MODE_PRIVATE).getAbsolutePath() + File.separator + DAEMON_BIN_NAME;/* create the command string */StringBuilder cmdBuilder = new StringBuilder();cmdBuilder.append(cmd);cmdBuilder.append(" -p ");cmdBuilder.append(context.getPackageName());cmdBuilder.append(" -s ");cmdBuilder.append(daemonClazzName.getName());cmdBuilder.append(" -t ");cmdBuilder.append(interval);try {Runtime.getRuntime().exec(cmdBuilder.toString()).waitFor();} catch (IOException | InterruptedException e) {Log.e(TAG, "start daemon error: " + e.getMessage());}
}

然后定时给自己主进程发一个intent,如果主进程挂掉了,就可以顺利拉起来保证存活。

while(sig_running)
{interval = interval < SLEEP_INTERVAL ? SLEEP_INTERVAL : interval;select_sleep(interval, 0);LOGD(LOG_TAG, "check the service once, interval: %d", interval);/* start service */start_service(package_name, service_name);
}

但这只是一个没有主动权的消息轮询器,说是守护其实很勉强,而且,这是要建立在保证c进程不挂的基础上,才能轮询,但是就目前来看,只有5.0以下的非国产机才会有这样的漏洞。也就是说在force close的时候,系统忽略c进程的存在,5.0以上包括5.0的哪怕源生系统也会连同c进程一起清理掉,国产机就更不用说了。就算是这样,在5.0以下的非国产机上,如果安装了获取root权限的360\cm的话,也是可以直接清理掉,也就是说会失效。

native进程守护缺点非常明显,那就是守护是单向的,也就是说只能a保b,b保不了a;a保b也不是在b死了立刻拉起来,要等到了时间才会去拉。那如何解决这个native进程的缺点呢?那就是通过双进程守护,下一篇我将详细讲解如何通过linux层来实现双进程守护。

这篇关于Android进程保活全攻略(中)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1089316

相关文章

Eclipse+ADT与Android Studio开发的区别

下文的EA指Eclipse+ADT,AS就是指Android Studio。 就编写界面布局来说AS可以边开发边预览(所见即所得,以及多个屏幕预览),这个优势比较大。AS运行时占的内存比EA的要小。AS创建项目时要创建gradle项目框架,so,创建项目时AS比较慢。android studio基于gradle构建项目,你无法同时集中管理和维护多个项目的源码,而eclipse ADT可以同时打开

android 免费短信验证功能

没有太复杂的使用的话,功能实现比较简单粗暴。 在www.mob.com网站中可以申请使用免费短信验证功能。 步骤: 1.注册登录。 2.选择“短信验证码SDK” 3.下载对应的sdk包,我这是选studio的。 4.从头像那进入后台并创建短信验证应用,获取到key跟secret 5.根据技术文档操作(initSDK方法写在setContentView上面) 6.关键:在有用到的Mo

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

Android我的二维码扫描功能发展史(完整)

最近在研究下二维码扫描功能,跟据从网上查阅的资料到自己勉强已实现扫描功能来一一介绍我的二维码扫描功能实现的发展历程: 首页通过网络搜索发现做android二维码扫描功能看去都是基于google的ZXing项目开发。 2、搜索怎么使用ZXing实现自己的二维码扫描:从网上下载ZXing-2.2.zip以及core-2.2-source.jar文件,分别解压两个文件。然后把.jar解压出来的整个c

android 带与不带logo的二维码生成

该代码基于ZXing项目,这个网上能下载得到。 定义的控件以及属性: public static final int SCAN_CODE = 1;private ImageView iv;private EditText et;private Button qr_btn,add_logo;private Bitmap logo,bitmap,bmp; //logo图标private st

Android多线程下载见解

通过for循环开启N个线程,这是多线程,但每次循环都new一个线程肯定很耗内存的。那可以改用线程池来。 就以我个人对多线程下载的理解是开启一个线程后: 1.通过HttpUrlConnection对象获取要下载文件的总长度 2.通过RandomAccessFile流对象在本地创建一个跟远程文件长度一样大小的空文件。 3.通过文件总长度/线程个数=得到每个线程大概要下载的量(线程块大小)。

时间服务器中,适用于国内的 NTP 服务器地址,可用于时间同步或 Android 加速 GPS 定位

NTP 是什么?   NTP 是网络时间协议(Network Time Protocol),它用来同步网络设备【如计算机、手机】的时间的协议。 NTP 实现什么目的?   目的很简单,就是为了提供准确时间。因为我们的手表、设备等,经常会时间跑着跑着就有误差,或快或慢的少几秒,时间长了甚至误差过分钟。 NTP 服务器列表 最常见、熟知的就是 www.pool.ntp.org/zo

高仿精仿愤怒的小鸟android版游戏源码

这是一款很完美的高仿精仿愤怒的小鸟android版游戏源码,大家可以研究一下吧、 为了报复偷走鸟蛋的肥猪们,鸟儿以自己的身体为武器,仿佛炮弹一样去攻击肥猪们的堡垒。游戏是十分卡通的2D画面,看着愤怒的红色小鸟,奋不顾身的往绿色的肥猪的堡垒砸去,那种奇妙的感觉还真是令人感到很欢乐。而游戏的配乐同样充满了欢乐的感觉,轻松的节奏,欢快的风格。 源码下载

Android SurfaceFlinger——图形内存分配器(十一)

前面的文章中的图层合成器(HWC),这里我们接着看一下 SurfaceFlinger 中的另一个重要服务——图形内存分配器。 一、简介         android.hardware.graphics.allocator@2.0 是 Android 系统中硬件抽象层(HAL)的一个组件,专门用于图形内存的分配和管理。它是 SurfaceFlinger 在处理图形数据时所依赖的

设置android返回键,保存和取得最高分

1.在.h中声明一些方法 virtual void keyBackClicked();           //Android返回键 bool isHaveSaveFile(); void getHighestHistoryScore(); 在.cpp中实现这个几个方法 void WelcomeLayer::keyBackClicked(