美文网首页安卓
【Android实例】1像素进程保活(一)

【Android实例】1像素进程保活(一)

作者: 秀叶寒冬 | 来源:发表于2019-07-23 22:41 被阅读0次

    1 进程保活

    1像素保活原理是,监听手机屏幕状态,如果手机黑屏,则启动一个1像素的Activity,减少该应用被回收的几率;在屏幕亮的时候,就关闭该Activity。1像素保活对某些手机不管用,亲测两款手机:红米5Note(Android 9)和华为G9青春版(Android 6.0)。

    测试方法:看是否调用1像素Activity。在打开应用,然后息屏情况下,两款手机都会调用1像素Activity;打开应用,然后点home键,再息屏,华为G9青春版(Android 6.0)会调用1像素Activity,但是红米5Note(Android 9)则不会调用。

    2管理类OnePixelManager

    首先建立一个OnePixelManager,该类是一个管理类。代码如下

    package com.yds.jianshu.onepixel;
    
    import android.app.Activity;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    
    import java.lang.ref.WeakReference;
    
    public class OnePixelManager {
        private static final String TAG = "[OnePixelManager]";
        private WeakReference<Activity> mActivity;
        private OnePixelReceiver onePixelReceiver;
    
        /**
         * 一像素广播接收者注册方法。该方法中初始化OnePixelReceiver,并添加了过滤条件
         * 屏幕息屏和亮屏。然后注册该广播接收者
         * @param context
         */
        public void registerOnePixelReceiver(Context context){
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_SCREEN_OFF);
            filter.addAction(Intent.ACTION_SCREEN_ON);
            onePixelReceiver = new OnePixelReceiver();
            context.registerReceiver(onePixelReceiver,filter);
        }
    
        /**
         * 对广播接收者进行解注册
         * @param context
         */
        public void unregisterOnePixelReceiver(Context context){
            if (null != onePixelReceiver){
                context.unregisterReceiver(onePixelReceiver);
            }
        }
    
        /**
         * 开启一像素Activity
         * @param context
         */
        public void startOnePixelActivity(Context context){
            Intent intent = new Intent();
            intent.setClass(context,OnePixelActivity.class);
            context.startActivity(intent);
        }
    
        /**
         * 关闭一像素Activity
         */
        public void finishOnePixelActivity(){
            if(null!=mActivity){
                Activity activity = mActivity.get();
                if(null!=activity){
                    activity.finish();
                }
                mActivity = null;
            }
        }
    
        /**
         * 使用弱引用获取一像素的上下文
         * @param activity
         */
        public void setKeepAliveReference(OnePixelActivity activity){
            mActivity = new WeakReference<Activity>(activity);
        }
    
    }
    
    
    

    3 广播接收系统发送的广播

    写一个一像素的广播接收者,接收息屏和亮屏时的广播

    package com.yds.jianshu.onepixel;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    
    
    public class OnePixelReceiver extends BroadcastReceiver {
        private static final String TAG = "[OnePixelReceiver]";
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            OnePixelManager manager = new OnePixelManager();
            if (Intent.ACTION_SCREEN_ON.equals(action)){//如果亮屏,则关闭1像素Activity
                manager.finishOnePixelActivity();
            }else if(Intent.ACTION_SCREEN_OFF.equals(action)){//如果息屏,则开启1像素Activity
                manager.startOnePixelActivity(context);
            }
        }
    }
    
    

    4 一像素Activity

    创建一个1像素的Activity,并将引用传给OnePixelManager

    package com.yds.jianshu.onepixel;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.util.Log;
    import android.view.Gravity;
    import android.view.Window;
    import android.view.WindowManager;
    
    public class OnePixelActivity extends Activity{
        private static final String TAG = "[OnePixelActivity]";
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            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);
            OnePixelManager manager = new OnePixelManager();
            manager.setKeepAliveReference(this);//将引用传给OnePixelManager
    
            Log.e(TAG,"onCreate");
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            Log.e(TAG,"onDestroy");
        }
    
        @Override
        protected void onStop() {
            super.onStop();
            Log.e(TAG,"onStop");
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            Log.e(TAG,"onPause");
        }
    
        @Override
        protected void onStart() {
            super.onStart();
            Log.e(TAG,"onStart");
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            Log.e(TAG,"onResume");
        }
    }
    
    

    5 MainActivity方法调用

    package com.yds.jianshu.mobile;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    
    import com.example.myapplication.R;
    import com.yds.jianshu.onepixel.OnePixelManager;
    
    public class MainActivity extends AppCompatActivity{
        private static final String TAG = "[MainActivity]";
        OnePixelManager manager;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            manager = new OnePixelManager();
            manager.registerOnePixelReceiver(this);//注册广播接收者
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            manager.unregisterOnePixelReceiver(this);//Activity退出时解注册
        }
    }
    
    

    6 AndroidManifest配置

    在OnePixelActivity注册的地方要加上以下三句

                android:excludeFromRecents="true"//#1
                android:launchMode="singleTask"//#2
                android:taskAffinity="com.yds.task"//#3
    
    • 第#1行,是为了让我们的1像素Activity在recents中看到,就是说,点击任务键(Android手机屏幕下三个键中的右边的键,一般是正方形那个)时不会看到OnePixelActivity
    • 第#2行,将启动模式设置为singleTask模式,配合taskAffinity使用。如果不设置,华为G9青春版(Android 6.0)会有问题,有时会创建多个OnePixelActivity,多次息屏亮屏,可能出现屏幕点不动,点击返回键后就正常,是因为创建了多个OnePixelActivity,通过打log日志也可以看出创建了多个OnePixelActivity。
    • 第#3行,将创建的OnePixelActivity放入指定的任务栈中

    代码如下:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.myapplication">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name="com.yds.jianshu.mobile.MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity android:name="com.yds.jianshu.onepixel.OnePixelActivity"
                android:excludeFromRecents="true"
                android:launchMode="singleTask"
                android:taskAffinity="com.yds.task"
                android:theme="@style/OnePixelActivity">
            </activity>
        </application>
    
    </manifest>
    

    7 优化部分

    将OnePixelActivity背景设置为透明

    <resources>
    
        <!-- Base application theme. -->
        <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
        </style>
        <!--设置背景-->
        <style name="OnePixelActivity" parent="android:Theme.Holo.Light.NoActionBar">//无标题
            <item name="android:windowIsTranslucent">true</item>//透明
        </style>
    </resources>
    
    

    源码:https://github.com/Yedongsheng/Jianshu/tree/develop

    【Android实例】1像素进程保活(一)
    【Android实例】1像素进程保活(二)

    相关文章

      网友评论

        本文标题:【Android实例】1像素进程保活(一)

        本文链接:https://www.haomeiwen.com/subject/xbyglctx.html