实现屏保有很多种方式,比如通过activity的onDispatchEvent不断判断最近一次操作的时间间隔,大于一个数的时候,弹出屏保的activity。我这里用 的是倒计时。之前用CountDownTimer和handler做过一版,发现维护起来比较麻烦,容易造成内存泄漏。
用rxjava实现倒计时
- 倒计时的关键代码 (参考https://www.jianshu.com/p/17af7790e8a6)
//倒计时的关键代码
public Observable<Integer> countdown(int delay, int time) {
if (time < 0) time = 0;
final int countTime = time;
Observable<Integer> observable = Observable.interval(delay, 1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(new Func1<Long, Integer>() {
@Override
public Integer call(Long increaseTime) {
return countTime - increaseTime.intValue();
}
})
.take(countTime + 1);
return observable;
}
全部代码如下
package com.wdedu.k12.tpad.base;
import android.content.Intent;
import android.view.KeyEvent;
import android.view.MotionEvent;
import com.wdedu.k12.tpad.util.LogUtils;
import com.wdedu.k12.tpad.util.SPStoreUtil;
import java.util.concurrent.TimeUnit;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;
import rx.subscriptions.CompositeSubscription;
import static com.wdedu.k12.tpad.config.WDConstant.Is_Share_Screen;
/**
* Created by cc on 2018/10/11.
*/
public abstract class BaseScreenActivity extends BaseActivity {
/* 静止超过N秒将自动进入屏保 */
private int mHoldStillTime = 10;
private static final int Screen_Req_Code = 110;
private CompositeSubscription mCompositeSubscription = new CompositeSubscription();
private boolean isWork = false;
/**
* 显示屏保
*/
private void showScreenSaver() {
Intent intent = new Intent(this, ScreenActivity.class);
startActivityForResult(intent, Screen_Req_Code);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Screen_Req_Code) {
startScreenProtect(0);
}
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
LogUtils.i("screen-- dispatchKeyEvent");
reStartScreenProtect();
return super.dispatchKeyEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
LogUtils.i("screen-- dispatchTouchEvent");
reStartScreenProtect();
return super.dispatchTouchEvent(ev);
}
@Override
protected void onDestroy() {
super.onDestroy();
mCompositeSubscription.clear();
}
protected void startScreenProtect(int delay) {
if (delay == 0) {
isWork = true;
}
Subscription subscribe = countdown(delay, mHoldStillTime)
.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
LogUtils.i("screen-- start gif screen protected");
showScreenSaver();
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Integer integer) {
LogUtils.i("screen-- stand time:" + integer + " thread name" + Thread.currentThread().getName());
}
});
if (mCompositeSubscription.hasSubscriptions()) {
mCompositeSubscription.clear();
}
mCompositeSubscription.add(subscribe);
}
protected void stopScreenProtect() {
mCompositeSubscription.clear();
isWork = false;
}
protected void reStartScreenProtect() {
if (isWork && SPStoreUtil.getBoolean(Is_Share_Screen)) {
mCompositeSubscription.clear();
startScreenProtect(3);
}
}
//倒计时的关键代码
public Observable<Integer> countdown(int delay, int time) {
if (time < 0) time = 0;
final int countTime = time;
Observable<Integer> observable = Observable.interval(delay, 1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(new Func1<Long, Integer>() {
@Override
public Integer call(Long increaseTime) {
return countTime - increaseTime.intValue();
}
})
.take(countTime + 1);
return observable;
}
}
屏保的activity就用一个半透明的activity即可。
public class ScreenActivity extends Activity {
private ImageView ivScreenGif;
private View rootView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_layout_screen);
initialized();
}
...
}
<style name="DialogActivity" parent="@style/AppTheme">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
在manifest文件中
<activity
android:name="com.wdedu.k12.tpad.activity.ScreenActivity"
android:launchMode="singleTop"
android:screenOrientation="landscape"
android:theme="@style/DialogActivity" />
网友评论