在開發中,有一些應用是需要常駐後臺運行:長期對某個事物的監聽或者長期掃描等。若手機鎖屏,有一定機率被系統給殺死。
在手機鎖屏之後避免應用給殺死,通過提高進程的優先級,使用1像素Activity進行保活。
原理:
當屏幕熄滅時,鎖屏狀態,調起一個一像素的Activity,提高進程的優先級。
一像素的Activity:
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.app.Activity;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Window;
import android.view.WindowManager;
import java.lang.ref.WeakReference;
/**
* @author Zachary
* 一像素保活
*/
public class ProtectActivity extends Activity {
public static WeakReference<ProtectActivity> weakReference;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initView();
initData();
initEvent();
}
protected void initView() {
weakReference = new WeakReference<>(this);
Log.e("save", "初始化");
Window window = getWindow();
//放在左上角
window.setGravity(Gravity.LEFT | Gravity.TOP);
WindowManager.LayoutParams params = window.getAttributes();
//起始座標
params.x = 0;
params.y = 0;
//寬高設計爲1個像素
params.height = 1;
params.width = 1;
window.setAttributes(params);
}
protected void initData() {
}
protected void initEvent() {
}
@Override
public boolean dispatchTouchEvent(MotionEvent motionEvent) {
finishSelf();
return super.dispatchTouchEvent(motionEvent);
}
@Override
public boolean onTouchEvent(MotionEvent motionEvent) {
finishSelf();
return super.onTouchEvent(motionEvent);
}
@Override
public void onResume() {
super.onResume();
if (isScreenOn()) {
finishSelf();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.e("save", "銷燬保活頁面");
if (weakReference != null && weakReference.get() == this) {
weakReference = null;
}
}
/**
* 關閉自己
*/
public void finishSelf() {
if (!isFinishing()) {
finish();
}
}
/**
* 判斷主屏幕是否點亮
*
* @return
*/
private boolean isScreenOn() {
PowerManager powerManager = (PowerManager) getApplicationContext()
.getSystemService(Context.POWER_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
return powerManager.isInteractive();
} else {
return powerManager.isScreenOn();
}
}
}
在AndroidManifest.xml配置:
ProtectActivity配置爲透明。
<activity android:name=".Activity.ProtectActivity"
android:launchMode="singleInstance"
android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
鎖屏廣播:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.zachary.util.Activity.ProtectActivity;
public class ScreenReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.e("save", "鎖屏");
Intent intentNew = new Intent(context, ProtectActivity.class);
intentNew.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intentNew);
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.e("save", "解鎖");
ProtectActivity protectActivity = ProtectActivity.weakReference != null ? ProtectActivity.weakReference.get() : null;
protectActivity.finish();
}
}
}
使用方法:
public class MainActivity extends SuperActivity{
private ScreenReceiver screenReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 保活,監控關屏幕
registerReceiver();
}
private void registerReceiver() {
screenReceiver = new ScreenReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(screenReceiver, intentFilter);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(screenReceiver);
}
}