- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 IntentService 实现番茄钟计时器,并且我似乎在管理 IntentService 中的计时器方面遇到了困难。我目前拥有的内容如下:
代码:
package com.nursson.pomodorotimer.service;
import android.app.IntentService;
import android.content.Intent;
import android.os.CountDownTimer;
import android.os.Looper;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.nursson.pomodorotimer.model.Pomodoro;
/**
* An {@link IntentService} subclass for handling asynchronous task requests in
* a service on a separate handler thread.
* <p/>
* helper methods.
*/
public class PomodoroService extends IntentService {
public static final String ACTION_CANCELLED = "com.nursson.pomodorotimer.service.pomodoro.action.CANCELLED";
public static final String ACTION_COMPLETE = "com.nursson.pomodorotimer.service.pomodoro.action.COMPLETE";
public static final String ACTION_START = "com.nursson.pomodorotimer.service.pomodoro.action.START";
public static final String ACTION_STOP = "com.nursson.pomodorotimer.service.pomodoro.action.STOP";
public static final String ACTION_TICK = "com.nursson.pomodorotimer.service.pomodoro.action.TICK";
public static final String EXTRA_TIME_REMAINING = "com.nursson.pomodorotimer.service.pomodoro.param.TIME_REMAINING";
private boolean started;
private CountDownTimer countDownTimer = new CountDownTimer(10000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
Intent tickIntent = new Intent(ACTION_TICK);
tickIntent.putExtra(EXTRA_TIME_REMAINING, millisUntilFinished);
LocalBroadcastManager.getInstance(PomodoroService.this).sendBroadcast(tickIntent);
Log.i("TIMER", "ticking...");
}
@Override
public void onFinish() {
started = false;
Intent tickIntent = new Intent(ACTION_COMPLETE);
LocalBroadcastManager.getInstance(PomodoroService.this).sendBroadcast(tickIntent);
Log.i("TIMER", "countdown Finished()");
Looper.myLooper().quit();
}
};
public PomodoroService() {
super("PomodoroService");
}
@Override
public void onCreate() {
super.onCreate();
Log.i("TIMER", "onCreate()");
}
@Override
public void onDestroy() {
super.onDestroy();
countDownTimer.cancel();
Log.i("TIMER", "onDestroy()");
}
@Override
public void onHandleIntent(Intent intent) {
if (intent == null) {
return;
}
switch (intent.getAction()) {
case ACTION_START:
handleStartAction();
break;
case ACTION_STOP:
handleStopAction();
break;
}
Looper.loop();
}
private void handleStopAction() {
Log.i("TIMER", "handleStopAction(): " + started);
if (started) {
Log.i("TIMER", "handleStopAction() - Cancel Timer");
started = false;
countDownTimer.cancel();
Intent tickIntent = new Intent(ACTION_CANCELLED);
LocalBroadcastManager.getInstance(PomodoroService.this).sendBroadcast(tickIntent);
}
}
private void handleStartAction() {
Log.i("TIMER", "handleStartAction()" + started);
if (!started) {
Log.i("TIMER", "handleStartAction() - Starting Timer");
started = true;
countDownTimer.start();
}
}
boolean isStarted() {
return started;
}
CountDownTimer getCountDownTimer() {
return countDownTimer;
}
}
代码中发生了什么
所以这基本上是一个 IntentService,其中包含一个 CountdownTimer 来向 Activity 广播消息。它还使用 Looper.loop(); 和 Looper.myLooper().quit(); 来尝试和管理生命周期。如果我不包含此内容,则会调用 onDestroy()
并且 CountdownTimer 会一直运行到最后。我希望在计时器结束后调用 onDestroy()
我得到的异常是当代码到达Looper.myLooper().quit();
时,这是下面的堆栈跟踪:
08-29 02:27:38.855 3337-3337/com.nursson.pomodorotimer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.nursson.pomodorotimer, PID: 3337
java.lang.IllegalStateException: Main thread not allowed to quit.
at android.os.MessageQueue.quit(MessageQueue.java:415)
at android.os.Looper.quit(Looper.java:228)
at com.nursson.pomodorotimer.service.PomodoroService$1$override.onFinish(PomodoroService.java:44)
at com.nursson.pomodorotimer.service.PomodoroService$1$override.access$dispatch(PomodoroService.java)
at com.nursson.pomodorotimer.service.PomodoroService$1.onFinish(PomodoroService.java:0)
at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:127)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
我想要发生什么
我希望能够使用 IntentService 启动和停止 CountDownTimer,并且在执行此操作时成为一个“好公民”。
最终目标是拥有一个可以持续通过方向变化并在 Activity 终止时继续运行的计时器。
到目前为止我尝试过的:
Looper.myLooper().quit();
。然后,当 CountDownTimer 完成时,onDestroy()
永远不会被调用。Looper
引用。然后 onDestroy()
被过早调用。计时器可以工作,但我无法获取对 CountDownTimer 的引用来取消它。我的想法:
最佳答案
我见过的所有Looper
示例都使用这种模式
Looper.prepare();
// create a handler
Looper.loop();
它为没有消息循环的线程创建并运行消息循环,处理程序用于与循环交互。
现在在您的代码中,我既没有看到 prepare
也没有看到 Handler
,所以首先您不遵循典型模式,而且还滥用了 Looper 的阻塞字符.loop()
以防止 onHandleIntent
终止。
在 onFinish
中调用 Looper.myLooper().quit()
不起作用,因为 CountDownTimer
方法似乎在主线程上运行,所以你试图退出主线程的消息循环。看起来不太喜欢。
如果您只需要阻止 onHandleIndent
直到执行 onFinish
,为什么不使用一种普通的 Java 线程模式呢?喜欢
private final Lock lock = new ReentrantLock();
private final Condition waitForFinish = lock.newCondition();
@Override
public void onHandleIntent(Intent intent) {
if (intent == null) {
return;
}
switch (intent.getAction()) {
case ACTION_START:
handleStartAction();
break;
case ACTION_STOP:
handleStopAction();
break;
}
lock.lock();
try {
while (started) {
waitForFinish.await();
}
} catch (InterruptedException ie) {
// log exceptions
} finally {
lock.unlock();
}
}
和
@Override
public void onFinish() {
started = false;
Intent tickIntent = new Intent(ACTION_COMPLETE);
LocalBroadcastManager.getInstance(PomodoroService.this).sendBroadcast(tickIntent);
Log.i("TIMER", "countdown Finished()");
lock.lock();
try {
waitForFinish.signal();
} finally {
lock.unlock();
}
}
缺点 - IntentService 在单个工作线程中处理请求,因此只要它在 onHandleIntent
中阻塞,它就不会接受新请求,例如停止计时器的请求(最好检查一下这一点,而不是相信我 - 我这里没有 Android SDK 来证明这一点)。
另一种解决方案是将阻塞调用放入 onDestroy
- 它会为新请求释放 onHandleIntent
并阻止服务在计时器完成之前完成。
或者使用另一种类型的服务——绑定(bind)或非绑定(bind),它在失业后不会自行破坏。但它们也有其缺点——两者都不是为了在主线程之外工作,这就是 IntentService 的用途。
关于java - 如何从 IntentService 中管理倒计时计时器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39200219/
我有一个包含很多歌曲的 ListView 。每次点击一首歌曲时,我都会调用一个 IntentService 来按顺序下载这首歌曲。 但有时我想取消下载(例如:第 5 次)。这意味着我需要停止第 5 个
我有这个 IntentService (HttpService),它从网络服务中获取原始 json 数据: public class HttpService extends IntentService
我想将回调传递给 IntentService。这是我当前的代码: 我的回调接口(interface) import android.os.Message; public interface Sampl
在我的 Android 应用程序中,我有一个带有适配器的简单 ListView 。有一个繁重的查询是用数据填充 ListView 。所以我把它放到另一个线程中运行的 IntentService 中。
我只想写一个“Hello World IntentService App”。不幸的是,我无法做到这一点。 问题: MyIntentService.enqueueWork() 方法不起作用。 Inten
我有 5 个 IntentServices,它们在与主 UI 不同的时间和单独的进程中运行。当服务完成时,它们通过 Intent 将数据发送到主进程。我想知道 5 个服务是否占用了我的应用程序过多的内
我正在构建一个应用程序,通知将在特定时间响起,如果无人看管 15 分钟,通知就会消失。当我插入设备并运行代码时它就可以工作。然而,一旦我拔掉设备并运行应用程序,通知就会起作用,但如果无人看管,它不会在
我构建了一个应用程序,它使用 IntentService 来操作应用程序的数据库和调用网络服务。 例子: 我有一个 Activity ,它是一个项目列表。此列表由 CursorAdapter 填充。每
我遇到了一个问题。 IntentService UpdateService02 偶尔会运行失败。我放入了日志条目以便进行调试,这就是我得到的... 02-28 21:37:32.461: Main -
我正在使用 IntentService 执行后台任务,例如从远程服务器更新数据。 在某些情况下,同一个请求可以被用户多次排队,但我只想执行一次(连续两次从服务器更新数据没有意义)。 是否有使用 Int
我正在使用 Android AlarmManger 安排 IntentService 在较小的间隔后运行。 这是我的 AlarmManger: static void setNextSchedule(
我的 IntentService 看起来像这样: public class MusicService extends IntentService{ final static String NA
我遇到了一个奇怪的情况,我构建的对象在方法 onHandleIntent 中返回为 null,我不知道为什么或如何解决它。 我的 Activity @Override protected vo
我搜索了很多,但我不知道如何在单击按钮时停止 IntentService。我有一个启动 IntentService 的按钮,然后 progressDialog 显示通过 ResultReceiver
我正在尝试用 Kotlin 编写一个 CallRecorder 应用程序。我想要做的是开始使用 BroadcastReceiver 启动的服务录制音频。我认为我在 MediaRecorder 初始化方
只是想阐明我对 IntentService 在达到 terminating 状态后如何由操作系统管理的理解。通过终止,我的意思是当当前 Activity 被销毁或应用程序进程被终止时,根据以下文档:
我正在使用 IntentService 访问不同的网络服务方法并更新我的 ContentProvider。我看到的问题是,有时,我向 IntentService 发送了一个新的 Intent,但是 I
我想我明白了 IntentService 类的意义。它处理一个队列,防止太多或更多的服务实例一起执行。 我发现它很有用,但是如果我从 IntentService 派生了太多具有不同用途的类,并且我希望
我有一个 IntentService,它在启动时启动并在后台保持运行。没有启动器 Activity,IntentService 由广播接收器调用。它适用于 2.3.4 和 4.0.4 设备,但不适用于
我编写了一个发送命令行的 IntentService。与我尝试对控制台进行编程的 Activity 有关。该 Activity 的目的是执行“命令提示符”,我可以在其中向服务器发送消息或从服务器接收消
我是一名优秀的程序员,十分优秀!