我试图创建使用计时器每30秒记录一次WAV文件的代码。
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
launchTask();
}
});
}
}, 0, 30000);
“启动任务()”开始记录wav文件。
问题是它每30秒尝试在任务仍在运行时再次启动它。
因此,在每30秒启动任务之前,需要立即取消该任务。
代码:
recordTask.cancel(false);
将取消任务,但不确定在计时器代码中调用它。
任何有关如何实现这一目标的建议都会被大加赞赏。
答案 0 :(得分:1)
我看到的问题是这是您正在创建的匿名方法。由于您已将其创建为匿名方法,因此它不易于访问。
我建议将“ launchTask”方法移到它自己的类中,实现Runnable接口,并将其视为线程。这样,您可以根据需要启动和停止它,以及创建(多个)实例。
http://tutorials.jenkov.com/java-concurrency/creating-and-starting-threads.html
这时,您可以将“超时”传递给该类,并且可能会自行停止。这是一个从上面的链接停止自身的类的示例。您应该能够包含一个带有参数的构造函数,该参数可以让您设置超时时间。您也可以在“ doStop”方法中包含任何代码以保存记录。这样,您可以使类完全以干净的OOP方式包含此功能所需的所有代码/方法。
public class MyRunnable implements Runnable {
private boolean doStop = false;
public synchronized void doStop() {
this.doStop = true;
}
private synchronized boolean keepRunning() {
return this.doStop == false;
}
@Override
public void run() {
while(keepRunning()) {
// keep doing what this thread should do.
System.out.println("Running");
try {
Thread.sleep(3L * 1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
如果您需要从当前位置管理线程,则可以执行此操作(也可以从链接页面):
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
try {
Thread.sleep(10L * 1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
myRunnable.doStop();
}
修改:
我只是记得,谷歌现在正在防止秘密使用麦克风和摄像头。如果未显示视频,则您将无法使用摄像头,并且麦克风也是如此。我不反对您使用它,因为我不知道它的用途,我只是在说要小心您的用途,并要注意Google有时可能会在过滤/时出错。搜索不允许的内容。
https://www.theverge.com/2018/3/7/17091104/android-p-prevents-apps-using-mic-camera-idle-background
答案 1 :(得分:0)
我建议使用AsyncTask
并在doInBackground
中执行30秒钟的录制。
例如(一些伪代码):
class RecordingTask extends AysncTask<Void, Void, WavObject> {
protected WavObject doInBackground() {
while (recordTime <= 30s) {
// keep recording
}
return wav;
}
protected void onPostExecte() {
// Handle with your wav here
}
}
在您的活动中:
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
new RecordingTask().execute();
}
});
}
}, 0, 30000);