Android 进程保活之—— "1像素页面"保活
2018-05-21 本文已影响0人
Batashi
一、MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.e(TAG, "--- onCreate ---");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 注册广播接收器,监听屏幕的状态
KeepLiveManager.registerBroadCast(this);
}
二、KeepLiveManager.java
package com.wei.wanandroid.activity.keeplive;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import com.wei.utillibrary.LogUtil;
/**
* @author: WEI
* @date: 2018/5/21
*/
public class KeepLiveManager
{
private static ScreenStateReceiver sScreenStateReceiver;
public static void registerBroadCast(Context context)
{
sScreenStateReceiver = new ScreenStateReceiver();
IntentFilter intentFilter = new IntentFilter();
// 亮屏时触发
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
// 锁屏时触发
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
// 解锁成功后触发
intentFilter.addAction(Intent.ACTION_USER_PRESENT);
context.registerReceiver(sScreenStateReceiver, intentFilter);
}
public static void unRegisterBroadCast(Context context)
{
if (sScreenStateReceiver != null)
{
context.unregisterReceiver(sScreenStateReceiver);
}
}
public static class ScreenStateReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
LogUtil.e("KeepLiveManager", intent.getAction());
if ( Intent.ACTION_SCREEN_ON.equals( intent.getAction() ) ||
Intent.ACTION_USER_PRESENT.equals( intent.getAction() ) )
{ // 亮屏或者解锁时对一像素界面进行销毁
KeepliveActivity.destroyOnePixelActivity();
}
else if ( Intent.ACTION_SCREEN_OFF.equals( intent.getAction() ) )
{ // 锁屏时启动一像素界面,此时进程的oom_adj=0,为android进程中最高优先级,
// 对应前台进程,通常不会被杀
KeepliveActivity.showOnePixelActivity();
}
}
}
}
三、KeepliveActivity.java
package com.wei.wanandroid.activity.keeplive;
import android.content.Intent;
import android.os.Bundle;
import android.view.Gravity;
import android.view.Window;
import android.view.WindowManager;
import com.wei.wanandroid.WanApplication;
import com.wei.wanandroid.activity.BaseActivity;
public class KeepliveActivity extends BaseActivity
{
private static KeepliveActivity sKeepliveActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sKeepliveActivity = this;
initWindow();
}
private void initWindow() {
Window window = getWindow();
window.setGravity(Gravity.LEFT | Gravity.TOP);
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.x = 0;
layoutParams.y = 0;
layoutParams.height = 1;
layoutParams.width = 1;
window.setAttributes(layoutParams);
}
@Override
public void initView() {
}
@Override
protected void onDestroy() {
super.onDestroy();
sKeepliveActivity = null;
}
public static void destroyOnePixelActivity() {
if (sKeepliveActivity != null)
{
sKeepliveActivity.finish();
}
}
public static void showOnePixelActivity() {
Intent intent = new Intent(WanApplication.getAppContext(),
KeepliveActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
WanApplication.getAppContext().startActivity(intent);
}
}
四、AndroidManifest.xml
<activity android:name=".activity.keeplive.KeepliveActivity"
android:excludeFromRecents="true"
android:finishOnTaskLaunch="false"
android:launchMode="singleInstance"
android:theme="@style/OnePixelActivityTheme">
</activity>
五、styles.xml
<style name="OnePixelActivityTheme" parent="AppTheme">
<item name="android:windowBackground">@android:color/transparent</item>
<!--<item name="android:windowBackground">@color/colorPrimaryDark</item>-->
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoDisplay">false</item>
<item name="android:windowDisablePreview">true</item>
</style>
六、测试结果
锁屏之后:
shell@libra:/ $ cat proc/18818/oom_adj
0
亮屏或解锁之后(锁屏之前app已经退到后台):
shell@libra:/ $ cat proc/18818/oom_adj
7
亮屏或解锁之后(锁屏之前app还在前台):
shell@libra:/ $ cat proc/18818/oom_adj
0
app退回桌面:
shell@libra:/ $ cat proc/18818/oom_adj
7
由上面测试结果可得出结论:锁屏后,进程的优先级为Android进程中最高级别,对应前台进程,oom_adj = 0。保活机率是最高的。但是,一旦app返回桌面后,oom_adj 就变为 7 了。所以,为了得到更好的保活效果,可以考虑在MainActivity的onPause函数体中启动一个Service,通过startForeground方式加强保活。