android休眠后恢复线程,关于Android系统休眠后,线程的执行情况
理论上,android系统休眠后,app进程会被挂起,所以相关的执行线程也会被挂起,那些java线程的操作例如:wait,await,sleep,循环阻塞,handler的delay,线程池的delay操作都会被挂起,因为它们使用的系统计时器在休眠的时候是停止的,例如:SystemClock.uptimeMillis(),其实针对不同版本的android系统这些表现各有不同,有些android系统是休眠后这些计时变慢了,原先计时5秒的,休眠后可能要计时5到6分钟,在android系统中AlarmManager可以解决上述问题,闹钟在系统休眠的时候也会唤醒系统的,闹钟使用的计时器在休眠的时候是继续跑的,例如:SystemClock.elapsedRealtime(),但是闹钟的计时并不是很准确,甚至有秒级别的误差:
1. setRepeating方法是重复的唤醒操作,根据api文档可知系统会对这些做优化,唤醒时间并不会严格的按照你设置的参数时间来执行
2. set方法在sdk版本低于19的实现是严格准确的按照设置的时间唤醒的,但是在sdk版本高于或者等于19的实现是经过优化的,并不会准确按照设置的时间唤醒,所谓的优化就是系统有可能判断到间隔时间很小的有两个闹钟唤醒操作,这时候系统可能就会自动的把比较早的那个闹钟唤醒操作和比较晚的唤醒操作合并为一个
3. 根据api文档说明,想要精确按照设置时间唤醒可采用setExact方法,但是据我真机(小米4C,6.0系统)实测,这个方法的唤醒任然存在较大误差,误差甚至到秒级别,有的会误差几秒钟,只能说基本准确
下面是测试代码:
补充一点:要把alarm和其他的定时测试分开执行,alarm唤醒之后会影响其他线程的测试的
public class MainActivity extends AppCompatActivity {
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
int i = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "sss", Toast.LENGTH_SHORT).show();
}
});
scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
String format = new SimpleDateFormat("HH:mm:ss").format(new Date());
NotificationUtil.showNotification(MainActivity.this, new Intent(), 100, "ScheduledExecutorService休眠测试", format + ":ScheduledExecutorService执行");
i++;
}
}, 20, 20, TimeUnit.SECONDS);
new Thread() {
@Override
public void run() {
long now;
while (true) {
now = SystemClock.elapsedRealtime();
while (SystemClock.elapsedRealtime() - now < 20000) ;
String format = new SimpleDateFormat("HH:mm:ss").format(new Date());
NotificationUtil.showNotification(MainActivity.this, new Intent(), 101, "Thread休眠测试", format + ":Thread执行");
}
}
}.start();
new Thread() {
@Override
public void run() {
while (true) {
synchronized (this) {
try {
this.wait(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String format = new SimpleDateFormat("HH:mm:ss").format(new Date());
NotificationUtil.showNotification(MainActivity.this, new Intent(), 102, "wait休眠测试", format + ":wait执行");
}
}
}.start();
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
sendEmptyMessageDelayed(1, 20000);
if (msg.what == 1) {
String format = new SimpleDateFormat("HH:mm:ss").format(new Date());
NotificationUtil.showNotification(MainActivity.this, new Intent(), 103, "handler休眠测试", format + ":handler执行");
}
}
};
handler.sendEmptyMessageDelayed(1, 20000);
new Thread(){
@Override
public void run() {
while (true) {
try {
sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String format = new SimpleDateFormat("HH:mm:ss").format(new Date());
NotificationUtil.showNotification(MainActivity.this, new Intent(), 104, "sleep休眠测试", format + ":sleep执行");
}
}
}.start();
startService(new Intent(this, TestService.class));
}
}
public class TestService extends Service {
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
HandlerThread handlerThread = new HandlerThread("ht");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
handler.post(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
scheduledExecutorService.schedule(new Runnable() {
@Override
public void run() {
String format = new SimpleDateFormat("HH:mm:ss").format(new Date());
NotificationUtil.showNotification(TestService.this, new Intent(), 105, "Service休眠测试", format + ":Service执行");
}
}, 0, TimeUnit.SECONDS);
}
}
});
Intent intent = new Intent(this, InnerGuardReceiver.class);
intent.setAction("com.xtc.watch.guard.push");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, -1001, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 20000, 20000, pendingIntent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
public static class InnerGuardReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String format = new SimpleDateFormat("HH:mm:ss").format(new Date());
NotificationUtil.showNotification(context, new Intent(), 106, "alarm休眠测试", format + ":alarm执行");
}
}
}
上面除了alarm会按时唤醒执行,其他的在手机休眠后计时变慢了,休眠越久,误差时间就拉的越大,都是20秒的定时任务,休眠后,除了alarm,其他的误差慢慢变大,例如一开始是30秒,然后1分钟,3分钟,5分钟,10分钟,16分钟等等,但是这些计时延迟的时间都基本一直,说明除了alarm,其他使用的系统计时器都是一致的
android休眠后恢复线程,关于Android系统休眠后,线程的执行情况相关推荐
- mysql重装系统后以前的数据_系统重装后,Mysql数据库重装加载原来数据库
mysql 5.6 后热数据的加载 mysql 5.6 后热数据的加载 转自:http://blog.itpub.net/20892230/viewspace-2127469/ 故障现象:在数据库重启 ...
- 服务器系统重装后要配置吗,服务器系统重装后要配置吗
服务器系统重装后要配置吗 内容精选 换一换 本节介绍将Windows操作系统的KVM实例变更为擎天架构实例的操作步骤.KVM实例:参考规格清单,查询对应规格的虚拟化类型.擎天架构实例:选择" ...
- linux 修改最大线程,修改linux系统用户最大线程数限制
遇到了坑就记下来,养成一个好习惯,利人利己.java tomcat启动后总是报错:java.lang.OutOfMemoryError: unable to create new native thr ...
- 装 linux后 win7消失了,win7系统重装后ubuntu启动消失不见的解决方法
很多小伙伴都遇到过win7系统重装后ubuntu启动消失不见的困惑吧,一些朋友看过网上零散的win7系统重装后ubuntu启动消失不见的处理方法,并没有完完全全明白win7系统重装后ubuntu启动消 ...
- win7安装系统后关闭计算机,一键重装系统win7后电脑无声音怎么办
一键重装系统win7后电脑无声音怎么办呢?天天有人学习一键重装系统,但不能保齐每个人重装系统都是顺利的,就譬如前几天有个网友问小编,一键重装系统win7后电脑无声音怎么办.遇到一键重装系统win7后电 ...
- 信号与系统陈后金matlab,信号与系统(陈后金)_MATLAB.ppt
信号与系统(陈后金)_MATLAB 信号与系统 Signals and Systems 利用MATLAB进行信号与系统分析 MATLAB简介 信号的MATLAB表示 利用MATLAB进行系统的时域分析 ...
- android 杀死进程广播,application 进程被系统杀死后,为何不能接受broadcast?
我针对三个action做了测试: android.net.wifi.WIFI_STATE_CHANGED android.net.wifi.STATE_CHANGED android.net.wifi ...
- java远程线程注入_系统权限远程线程注入到Explorer.exe
提升为系统权限,注入到explorer中 一丶简介 我们上一面说了系统服务拥有系统权限.并且拥有system权限.还尝试启动了一个进程. 那么我们是不是可以做点坏事了. 我们有一个系统权限进程.而调用 ...
- 电脑系统更新后无法连接服务器,win10 系统更新后,SQL数据库无法连接
满意答案 bese8d1r76 2018.06.13 采纳率:45% 等级:9 已帮助:764人 自从微软发布Win10正式版系统以后,很多用户都对自己的电脑进行了系统升级.可是有的用户在更新系 ...
- lumia flash android,IT之家学院:将刷了Android的Lumia恢复为WP系统
昨天IT之家已经教给大家如何将Lumia 520/521/525/526/720刷成Android系统,在文章的开头,IT之家提到过,刷了Android的Lumia的包括相机在内的一些部件不能正常工作 ...
最新文章
- R语言使用ggplot2包使用geom_violin函数绘制分组小提琴图(分组颜色配置、位置配置)实战
- 【C 语言】二级指针作为输入 ( 二维数组 | 抽象业务函数 | 二维数组打印函数 | 二维数组排序函数 )
- 微信小程序(6)模板详解 template
- 微信编辑照片到底该不该增加滤镜功能?
- 如何用苹果手机生成扫描件
- Scala入门示例反编译分析代码执行流程
- 在银行存款被吞了,怎么能快速解决?
- Enterprise Library v5.0 -- Data Access Application Block 开发向导(3)
- python 生成器 generator
- Maven3路程(六)用Maven创建Spring3 MVC项目
- 饭团(0):提升效率的开发工具
- hibernate注解方式实现一对多映射
- Mac电脑:Android Studio 连接 MUMU 网易模拟器
- 前自增和后自增的比较
- Confluence3.4的安装和配置
- html5新增graph,Qunee for HTML5 - 中文 : Graph组件介绍
- 有没有想过Surface只是伪刚需?
- 【Excel】定位条件快速将空值替换为指定值
- MySQL3:连接查询、子查询及正则表达式查询
- 【bzoj 1022】 小约翰的游戏John 【SHOI2008】
热门文章
- html5图片长按保存,一文彻底解决HTML5页面中长按保存图片功能
- Android studio ERROR: Software caused connection abort: recv failed 解决方法
- NotificationManager: notifyAsUser: tag=null, id=6, user=UserHandle{0}
- FileZilla Server 搭建FTP服务器
- Oracle rman备份和还原恢复数据库
- android使用menu需要重写的方法,Android – 正确使用invalidateOptionsMenu()
- div跳转html页面底部,即使没有内容,如何强制DIV块扩展到页面底部?
- 基于jquery.ajax的进一步封装
- 面试 jsp转发和重定向
- (JAVA)String类之比较方法