Trouble with getting thread to sleep - Android - handler

I'm pretty new to java (first post) and trying to make a loop that does the following:
Post to a textview, Wait, Post to another textview, Wait, Clear both (by posting " " to each one), Sleep, Repeat loop.
The loop send the messages to the que almost instantaneously, without doing the sleep part inbetween
Runnable postRight = new Runnable() {
public void run() {
right_side.setText("post right");
}
};
Runnable postLeft = new Runnable() {
public void run() {
left_side.setText("post left");
}
};
Runnable clear = new Runnable() {
public void run() {
left_side.setText(" ");
right_side.setText(" ");
}
};
/////////////////////////////////////////////////////////////
while (i < 3) {
Log.i(TAG, "Entered while");
long Timer = SystemClock.uptimeMillis();
handler.postAtTime(postLeft, Timer + 1000);
Log.i(TAG, "post left");
handler.postAtTime(postRight, Timer + 2000);
Log.i(TAG, "postright");
handler.postAtTime(clear, Timer + 3000);
Log.i(TAG, "clear");
Thread t = new Thread() {
public void run() {
try {
Thread.sleep(4000);
runOnUiThread(new Runnable() {
public void run() {
Log.i(TAG, "inside runnable");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t.start();
i++;
}

the thread t is sleeping, but it's its own thread, so the main thread just keeps on going after initiating and the main thread never sleeps

Related

WebFlux issue when creating a global publisher subscription

I have written to the publisher and it works if they subscribe to it every time. The problem arises when I try to make it global so that all subscribers receive the same messages.
Here is my code :
public class MyPublisherDemo {
private final ArrayBlockingQueue<SavedEvent> myBlockingQueue = new ArrayBlockingQueue<>(100, true);
private final Flux<SavedEvent> fx = Flux.create(event -> {
try{
while(true){
Thread.sleep(5000);
if(myBlockingQueue.isEmpty()){
System.out.println("back");
break;
}
event.next(myBlockingQueue.poll());
System.out.println("next");
}
event.complete();
System.out.println("complete");
}catch (Exception e) {
event.error(new RuntimeException(e));
}
});
private final ConnectableFlux<SavedEvent> cf = fx.publish();
public Flux<String> getFluxTest(SavedEvent savedEvent){
myBlockingQueue.add(savedEvent);
cf.connect();
return cf.map(SavedEvent::getOccurredEvent);
}
public int getQueueSize(){
return myBlockingQueue.size();
}
}
And I wrote the following test to check:
#Test
public void test5(){
try {
MyPublisherDemo myPublisherDemo = new MyPublisherDemo();
Runnable task = () -> {
System.out.println(Thread.currentThread().getName() + " Run");
myPublisherDemo.getFluxTest(new SavedEvent().builder()
.id(1L)
.occurredEvent("(" + Thread.currentThread().getName() + ")" + " Coffee Machine start")
.eventTime(LocalDateTime.now())
.fillTheWaterTank(1000)
.fillCoffeeTank(1000)
.build())
.subscribe(
event -> System.out.println(Thread.currentThread().getName() + " " + event),
System.out::println,
() -> System.out.println(Thread.currentThread().getName() + " end")
);
};
Thread th1 = new Thread(task, "thread-1");
th1.start();
Thread.sleep(2000);
Thread th2 = new Thread(task, "thread-2");
th2.start();
Thread.sleep(20000);
System.out.println("Queue size = " + myPublisherDemo.getQueueSize());
System.out.println("Basic thread run. End program.");
}catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
The structure of SavedEvent I think is clear from builder().
The point of the publisher is to wait for the event for 5 seconds if the current event is still being processed.
The version I used before:
private final ArrayBlockingQueue<SavedEvent> myBlockingQueue = new ArrayBlockingQueue<>(100, true);
private final AtomicInteger counterRequest = new AtomicInteger(100);
private final Flux<SavedEvent> fx = Flux.fromIterable(myBlockingQueue)
.delayElements(Duration.ofSeconds(7))
.map(data ->{
myBlockingQueue.poll();
counterRequest.decrementAndGet();
return data;
})
.repeat(counterRequest.get());
private final ConnectableFlux<SavedEvent> cf = fx.publish();
Problem when working with two subscribers they don't receive all messages.
thread-1 Run
thread-2 Run
thread-1 (thread-1) Coffee Machine start
next
thread-1 (thread-2) Coffee Machine start
next
back
thread-1 end
complete
Queue size = 0
Basic thread run. End program.
The result I'm expecting:
thread-1 Run
thread-2 Run
thread-1 (thread-1) Coffee Machine start
thread-2 (thread-1) Coffee Machine start
next
thread-2 (thread-2) Coffee Machine start
thread-1 (thread-2) Coffee Machine start
next
back
thread-1 end
complete
back
thread-2 end
complete
Queue size = 0
Basic thread run. End program.
If the error is in how I'm trying to implement the publisher, please write how it should be done correctly. Thank you in advance.
While experimenting with RxJava I found a solution on the net:
let myObservable = Observable.just(1).publish()
print("Subscribing")
myObservable.subscribe(onNext: {
print("first = \($0)")
})
myObservable.subscribe(onNext: {
print("second = \($0)")
})
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
print("Calling connect after 3 seconds")
myObservable.connect()
}
It's not obvious, but for the first subscriber, you first need to have a subscription to the publisher and then you need to start the publisher.I did not understand why this is so. It works.
public class MyPublisherDemo {
private final ArrayBlockingQueue<SavedEvent> myBlockingQueue = new ArrayBlockingQueue<>(100, true);
private final AtomicBoolean connectFlag = new AtomicBoolean(false);
private final ConnectableFlux<String> myEventGenerator = Flux.create(event ->{
try{
while(true){
Thread.sleep(5000);
if(myBlockingQueue.isEmpty()){
break;
}
event.next(myBlockingQueue.poll());
}
connectFlag.getAndSet(false);
event.complete();
}catch (Exception e) {
event.error(new RuntimeException(e));
}
}).map(event -> {
SavedEvent se = (SavedEvent) event;
return se.getOccurredEvent();
}).publish();
public Flux<String> getFluxTest(SavedEvent savedEvent){
myBlockingQueue.add(savedEvent);
delayedStart();
return myEventGenerator;
}
public int getQueueSize(){
return myBlockingQueue.size();
}
private void delayedStart(){
if (!connectFlag.getAndSet(true)) {
Runnable task = () -> {
try {
Thread.sleep(500);
myEventGenerator.connect();
} catch (Exception e) {
System.err.println(e);
}
};
Thread th1 = new Thread(task);
th1.start();
}
}
}

give delay in showing the controls

I would like to add the button controls in a timely manner.
That means, after the shell opened, it should start placing the buttons one by one
in a 1 second delay. I wrote the program,however it does not work. all the buttons
are visible only after all the controls are placed. Some kind of refresh issue I guess.
Following is my code.
public class DelayAddingComponentsExample {
public static void main(String[] args) {
Display display = new Display();
final Shell shell = new Shell(display);
shell.setSize(200, 200);
shell.setLayout(new FillLayout(SWT.VERTICAL));
addAutomatically(shell);
// removeAutomatically(shell);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
public static void addAutomatically(final Shell shell) {
for (int i = 0; i < 5; i++) {
final Button button = new Button(shell, SWT.NONE);
button.setText("Button" + i);
button.setVisible(false);
}
shell.getDisplay().timerExec(0, new Runnable() {
#Override
public void run() {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(500);
final Button button = new Button(shell, SWT.NONE);
button.setText("Button" + i);
button.setVisible(true);
shell.pack();
shell.layout(true);
shell.redraw();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
public static void removeAutomatically(final Shell shell) {
for (int i = 0; i < 5; i++) {
final Button button = new Button(shell, SWT.NONE);
button.setText("Button" + i);
shell.layout(true);
}
shell.getDisplay().timerExec(0, new Runnable() {
#Override
public void run() {
Control[] controls = shell.getChildren();
for (Control control : controls) {
try {
Thread.sleep(500);
control.dispose();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
}
The Runnable given to timerExec runs in the UI thread. So the Thread.sleep calls you are making are blocking the UI thread - it is vital that you never block this thread. Never call Thread.sleep in the UI thread.
You must do each step using a separate timeExec call and use the delay parameter of the timerExec call to specify how long to wait.
So
shell.getDisplay().timerExec(500, new Runnable() {
#Override
public void run()
{
// TODO code for the first button only
// Schedule next update
shell.getDisplay().timerExec(500, .... code for second button);
}
});
Runs the Runnable after 500 millseconds, the Runnable should just do the first step and then call timerExec again to schedule the next step.

Periodical Agent - Await for searchasync on Appointments

I am performing a
appts.SearchAsync
on
var appts = new Appointments();
In a "Periodical Agent".
The problem is that in the periodical agent. The searchasync and it's nested functions never finish before
NotifyComplete();
}
Could you please help me on how to wait for all the calls that are being done in here:
static void Appointments_SearchCompleted(object sender, AppointmentsSearchEventArgs e)
{
try
{
UpdatePrimaryTile(e.Results
.Where(a => a.Subject != null)
.OrderBy(a => a.StartTime)
.ToList());
}
catch (System.Exception)
{
}
}
public static void UpdatePrimaryTile(List<Appointment> calendarItems)
{
...........
..........
}
Before "NotifyComplete" is being called.
Thank you!
Jakub
You can use the await keyword to wait for an async operation to complete.
await appts.SearchAsync
Another option - have a loop that sleeps until the async call completes.
appts.SearchAsync
while (true)
{
if (searchCompleted)
{
break;
}
else
{
Thread.Sleep(100);
}
}
then in the event handler...
void Appointments_SearchCompleted(object sender, AppointmentsSearchEventArgs e)
{
searchCompleted = true;
// Other logic
}

Improve software responsiveness when slider is manipulated in windows phone

I have a slider in my windows phone 7.1 project. When manipulated, this slider fires an event which starts a background worker to performs several trigonometric operations.
If I move the cursor on the slider, I have a certain delay in the response although I have implement background worker cancelAsync method in manipulationstarted event, I would like more responsiveness, how can I achieve this?
Code:
private void sliderCosinus_ManipulationStarted(object sender,ManipulationStartedEventArgs e)
{
if (bw.WorkerSupportsCancellation == true)
{
bw.CancelAsync(); // Cancel the asynchronous operation.
}
}
private void sldCosinus_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
try
{
Value = Convert.ToInt32(sldCosinus.Value) * 10;
}
catch
{
// errore message here
}
finally
{
}
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
if ((worker.CancellationPending == true))
{
e.Cancel = true;
}
else
{
Dispatcher.BeginInvoke(() => app.IsEffectApplied=TrigonometricTrans()
// TrigonomtriecTrans calculate sin and cosinus for every pixel in image
}
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// progress bar here
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ((e.Cancelled == true))
{
//this.tbProgress.Text = "Canceled!";
}
else if (!(e.Error == null))
{
//this.tbProgress.Text = ("Error: " + e.Error.Message);
}
else
{
DoubleBufferToScreen();
}
}

com.google.android.voicesearch.speechservice.ConnectionException: Failed to establish connection

I am testing an app that makes voice recognition, but now I am getting this error:
11-04 16:25:58.249: E/ServerConnectorImpl(13716): Failed to create TCP connection
11-04 16:25:58.249: E/ServerConnectorImpl(13716): com.google.android.voicesearch.speechservice.ConnectionException: Failed to establish connection
11-04 16:25:58.249: E/ServerConnectorImpl(13716): at com.google.android.voicesearch.tcp.TcpConnectionImpl.<init>(TcpConnectionImpl.java:87)
....
Here is my code:
sr = SpeechRecognizer.createSpeechRecognizer(getApplicationContext());
MyRecognition listener = new MyRecognition();
sr.setRecognitionListener(listener);
Class MyRecognition that implements the methods from RecognitionListener
class MyRecognition implements RecognitionListener{
public void onBeginningOfSpeech() {
}
public void onBufferReceived(byte[] buffer) {
}
public void onEndOfSpeech() {
}
public void onError(int error) {
MediaPlayer mp = new MediaPlayer();
AssetFileDescriptor asset;
try {
asset = getAssets().openFd("error.mp3");
mp.setDataSource(asset.getFileDescriptor(), asset.getStartOffset(), asset.getLength());
asset.close();
mp.prepare();
mp.start();
mp.setOnCompletionListener(AddActivity.this);
} catch (IOException e) {
e.printStackTrace();
}
}
....
public void onResults(Bundle results) {
....
}
....
}
The method that makes the voice recognition
private void reconheceVoz(final MediaPlayer mp){
try{
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, "com.br.test");
intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5);
sr.startListening(intent);
mp.release();
}
catch(Exception e){
Toast.makeText(AdicaoActivity.this, "Erro: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
This error occurs often? How can I treat it?
Thanks.