【发布时间】:2015-10-16 00:37:05
【问题描述】:
我正在制作一个按时间间隔执行操作的应用程序。我可以在两次更新之间等待的绝对最长时间是 30 秒,介于 0 和 0 之间的任何时间都是可以接受的,但我更喜欢 15 秒。然而,它并不像听起来那么容易。我尝试了4种方法,由于各种原因都无法接受。
请记住,这些问题发生在 Service 中,当此代码在 Activity 中运行时,它运行良好。我还注意到,当手机插入我的计算机进行调试时,解决方案 3 运行良好,直到我将其拔出。我检查了我的电池设置,没有电池省电模式或其他类似的东西,这可能是这个原因。
1.IntentService 做一些事情,然后在 15 秒内重新安排自己。不幸的是,当警报准确时,AlarmManager.setExact() 完全不可靠,正如我在这篇风滚草中所描述的那样:Android Alarm not triggering at exact time
2.具有Thread 的前台服务。在那个线程中,我做我的事情,然后sleep() 15 秒。结果证明这个方法比以前更糟糕,线程被唤醒到超过正确时间 5 分钟。
3.然后我尝试使用Timer(如geokavel 建议的那样)并使用scheduleAtFixedRate 和schedule 安排工作,但工作完成时间晚了约15-45 秒,使间隔改为约1 分钟15 秒。
4.我想到的最后一种实现方法是不要从上面的前台服务中的Thread 中睡觉。相反,我比较时间:
public void run(){
nextTime = System.currentTimeMillis() + sleep;
while (true){
if (System.currentTimeMillis() >= nextTime) {
nextTime = System.currentTimeMillis() + sleep;
//do stuff
}
}
}
除了一个主要缺点之外,这种方法的工作原理很像一个魅力 - 它一直使用 20-25% 的 CPU。
所以我的问题是,有没有办法使上述解决方案正常工作(没有不可接受的缺点)?如果没有,有没有更好的方法我错过了?如果需要,请随时询问更多详细信息。
编辑:请求的 run() 代码:
public void run(){
try {
if (Thread.currentThread().isInterrupted()){
throw new InterruptedException();
}
NetworkInfo info = cm.getActiveNetworkInfo();
if (info == null) {
throw new UnknownHostException();
}
if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
Log.i(TAG, "Won't use mobile connection");
throw new UnknownHostException();
} else {
internetRestored();
st.updateData();
}
} catch (MalformedURLException | UnknownHostException e) {
internetFailed();
Log.e(TAG, "No internet connection, cant log");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
Log.i(TAG, "Thread iterrupted");
}
}
【问题讨论】:
标签: android multithreading service