Android图片管理工具 弹窗 保活 音乐播放器 自定义View 计步器 项目框架

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方式加强保活

上一篇下一篇

猜你喜欢

热点阅读