Сон Одера жди в течение-петли
Я пытаюсь включить светодиод на определенную длину (out_tic), основываясь на заданном тексте в азбуке Морзе(Text). Я попытался решить эту проблему с помощью "postDelay", а также с помощью sleep() или wait (), но вспышка всегда имеет одинаковую длину или приложение вылетает.. Я думаю, это потому, что вспышка должна начаться, когда она еще не закрылась.
cam = Camera.open();
Handler handler = new Handler();
for(int i=0;i<Text.length();i++){
if(Text.charAt(i)=='.' ||Text.charAt(i)=='·'){
ledon();
handler.postDelayed(new Runnable() {
public void run() {
ledoff();
}
}, out_tic);
}
else if(Text.charAt(i)=='-'){
ledon();
handler.postDelayed(new Runnable() {
public void run() {
ledoff();
}
}, 3*out_tic);
}
else if(Text.charAt(i)=='/'){
if(Text.charAt(i-1)=='/'){
}
}
}
Методы ledon() и ledoff () просто устанавливают параметры и запускают/останавливают предварительный просмотр.
Спасибо за помощь!
Новый код это работает для меня:
(Благодаря JRaymond)
final String Text = "./-..-/.-/--/.--./.-.././/";
final int out_tic = 200;
new Thread(new Runnable(){
@Override
public void run() {
for(int i=0;i<Text.length();i++){
if(Text.charAt(i)=='.' ||Text.charAt(i)=='·'){
flash(out_tic);
flashpause(out_tic);
continue;
}
else if(Text.charAt(i)=='-'){
flash(3*out_tic);
flashpause(out_tic);
continue;
}
else if(Text.charAt(i)=='/'){
flashpause(2*out_tic);
if(Text.charAt(i-1)=='/'){
flashpause(4*out_tic);
}
}
}
}
}).start();
}
private Handler handler = new Handler();
private void flash(final int sleeptime) {
handler.post(new Runnable() {
@Override
public void run() {
ledon();
}
});
try {
Thread.sleep(sleeptime);
} catch (InterruptedException e){
}
handler.post(new Runnable(){
public void run() {
ledoff();
}
});
}
private void flashpause(final int sleeptime) {
try {
Thread.sleep(sleeptime);
} catch (InterruptedException e){
}
}
private Camera cam;
private void ledon() {
cam = Camera.open();
Parameters params = cam.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_TORCH);
cam.setParameters(params);
cam.startPreview();
}
private void ledoff() {
cam.stopPreview();
cam.release();
}
1 ответ:
Я думаю, что разобрал вашу головоломку-все ваши раннаблы публикуются так, что они происходят почти в одно и то же время.
postDelayed
планируетRunnable
на время, начиная с этого момента, а не с того времени, когда был запланирован последнийRunnable
. Я думаю, что вашим лучшим решением будет что-то вроде этого, которое разгружает управление светодиодом в другой поток:cam = Camera.open(); Handler handler = new Handler(); new Thread(new Runnable() { public void run() { for(int i=0;i<Text.length();i++){ if(Text.charAt(i)=='.' ||Text.charAt(i)=='·') { flash(out_tic); continue; } else if(Text.charAt(i)=='-'){ flash(3 * out_tic) continue; } // I don't quite understand what this does, but the same principles apply else if(Text.charAt(i)=='/'){ //Warte 2*out_tic lang (1mal wurde schon gewartet) if(Text.charAt(i-1)=='/'){ } } } } private void flash(int tic) { handler.post(new Runnable() { public void run() { ledon(); } }); try { Thread.sleep(out_tic); } catch (InterruptedException e) { } handler.post(new Runnable() { public void run() { ledoff(); } } } });
Обратите внимание, что выше довольно грязно, вы можете захотеть переместить вещи и немного очистить его - но идея в том, что вы позволяете другой поток из пользовательского интерфейса делает спящий режим, а затем отправляет обратно в обработчик, когда параметры камеры должны быть изменены.