I'm trying to move a file after its being played.
I'm using javazoom's basicplayer to play my files and I tried
player.close();
controler.close();
and DSP.close();
and none work
Here is the code I use to play the file
public void play(File sound) {
if (sound.exists()) {
new Thread("Sound player") {
public void run() {
currentSelectedSound = sound;
try {
control.open(currentSelectedSound);
control.play();
setVolume(currentAudioVolume);
setPan(currentAudioPan);
} catch (BasicPlayerException e) {
e.printStackTrace();
System.err.println("Error!");
}
}
}.start();
} else {
Logger.logError(TAG, "File doesn't exist!");
}
}
I'm so happy it finally works, heres the answer for anyone :
stop();
try {
//The thread used to play() the sound
soundPlayThread.join();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
//Manually run the garbage collection and yield threads
System.gc();
Thread.yield();
I hope no one wastes 6 hours like I just did
Extreme big thanks to wuppi
https://stackoverflow.com/a/14123384/3224295
Related
I'm having an app which enables a customer to place an order for a ride (as in Uber), initially considered in a "WAITING" phase. When a driver accepts the order, it is automatically set in an "ACCEPTED" phase.
When ACCEPTED, the user is going to be redirected to another scene, telling him that he needs to wait for his rider to pick him up.
I decided to create a thread that checks every 250ms if the status of his order was set to ACCEPTED, like that:
public class AcceptanceRunnable implements Runnable {
private boolean running;
public AcceptanceRunnable() {
running = true;
}
public void run() {
do {
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (OrderService.checkIfAccepted(OrderSession.getOrder())) {
// move to other scene
break;
}
} while(running);
}
public void setRunning(boolean running) {
this.running = running;
}
}
This AcceptanceRunnable class gets instantiated within the controller in the initialize() method:
#FXML
public void initialize() throws InterruptedException, IOException {
sourceAddress.setText("From: " + OrderSession.getOrder().getSourceAddress());
destinationAddress.setText("To: " + OrderSession.getOrder().getDestinationAddress());
price.setText("You'll need to pay RON " +
UserService.calculatePrice(UserSession.getUser()) + " for this ride.");
acceptanceRunnable = new AcceptanceRunnable();
Thread t = new Thread(acceptanceRunnable);
t.start();
}
Everything works fine. If I just print out some lines while waiting for the order's status to get changed, it seems to be okay. The problem is, I want my user to be redirected to another scene, if his order gets accepted.
This means, I need to insert something in place of the comment made in my AcceptanceRunnable.run() method.
I also tried changing the scene by having a method called ifAccepted() inside my controller, which actually triggers the method that changes the scene:
if (OrderService.checkIfAccepted(OrderSession.getOrder())) {
try {
Class<?> controller = Class.forName("com.example.yuber.controllers.CustomerWaitController");
Method ifAccepted = controller.getMethod("ifAccepted");
ifAccepted.invoke(controller.newInstance());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
break;
}
But I only get some NullPointerException and I'm pretty sure that what I do here isn't really correct.
Any opinions?
As Slaw suggested, using Platform#runLater(Runnable) fixed my problem.
What I actually did was add my run() method from the Runnable inside my controller, renaming it to handleTread():
public void handleThread() {
do {
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (OrderService.checkIfAccepted(OrderSession.getOrder())) {
Platform.runLater(() -> {
try {
SceneService.NewScene("/com/example/yuber/accepted-view.fxml", (Stage) rootPane.getScene().getWindow(), rootPane.getScene());
} catch (IOException e) {
e.printStackTrace();
}
});
break;
}
} while(running);
}
Not using Platform.runLater(...) would result in receiving a Not on FX Application Thread error.
Everything seems to be fine now.
I'm using the ReadData class from https://github.com/iota-community/java-iota-workshop/blob/master/src/main/java/com/iota/ReadData.java to retrieve a message from the Iota Tangle (essentially a distributed Network) via a hash value (the bundlehash).
That's my method:
private String readMessageFromHash(String BundleHash) {
final String[] s = new String[]{""};
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
s[0] = ReadData.getTMessage(BundleHash);
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return s[0];
}
I need the return value in my next line of code but without multithreading my program crashes.
With mutlithreading it sometimes works, but most of time it doesn't work (returns an empty String).
I tried using:
thread.start();
try {
while(s[0].length < 1){}
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return s[0];
but it just loops infinitely.
I think the issue is my program not waiting long enough for a response from the network.
I have three threads and they need some resources to run (A,B,C) that I have implemented using Semaphores.
public void run(){
while(!Thread.currentThread().isInterrupted){
try{
A.acquire(2);
B.acquire(2);
//some-stuff
}
catch(InterruptedException ex){}
finally{
A.release(2); //PROBLEM
B.release(2);
}
}
Problem: while running, the thread could be interrupted but, going in the finally method I don't know where I was during the interruption so I don't know if I have to release something or not.
I have tried a lot of different implementation, like using the method (boolean) tryAcquire() but another problem comes up: if I get the resource A but not the B, then in the finally block I would release the A again etc.
Do you have any suggestions? Thank you.
Use nested try blocks:
try {
A.acquire(2);
try {
B.acquire(2);
try {
// some stuff
} finally {
B.release(2);
}
} finally {
A.release(2);
}
} catch (InterruptedException ex) {}
You could try to use List like this:
List<Semaphore> acquired = new ArrayList<>(2);
while(!Thread.currentThread().isInterrupted) {
try{
A.acquire(2);
acquired.add(A);
B.acquire(2);
acquired.add(B);
//some-stuff
} catch(InterruptedException ex){}
finally{
for (Semaphore s : acquired) {
s.release(2);
}
s.clear();
}
}
I am doing a small project for my girlfriends grandparents, that have a hard time using a computer so I thought I would be able to write something that might fix their problem. Here is the code first off:
import java.io.IOException;
public class OpenWordPad {
public static void main(String[] args) {
try {
System.out.println("Opening WordPad");
Runtime runTime = Runtime.getRuntime();
Process process = runTime.exec("wordpad");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Closing WordPad");
process.destroy();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(had to indent some so sorry if it is a little wonky)
When I put notepad in the process line it works fine but when I put in wordpad it freaks out. I want to be able to open wordpad so I can put it on their computer. Any suggestions?
For that you can use runTime.exec("write"):
import java.io.IOException;
public class OpenWordPad {
public static void main(String[] args) {
try {
System.out.println("Opening WordPad");
Runtime runTime = Runtime.getRuntime();
Process process = runTime.exec("write"); // <--- here
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Closing WordPad");
process.destroy();
} catch (IOException e) {
e.printStackTrace();
}
}
}
opens WordPad.
Here's the deal, I need to run an operation, and show a progress bar while it runs. I figured I need to run the progress bar update on a different thread, because if I don't (I have tried) the bar doesn't get updated before the end of the operation. I have written the code bellow, however it isn't working, crashing the app instead. I believe the problem is related to the synchronization between threads, but I'm not sure (second time working with Java threads, please spare me, I'm still a newbie). This is running on Android.
Can you spot any illegal operation I'm not aware of? Thanks!
ProgressDialog progress; //Global, declared somewhere else
final Object flag = new Object();
Thread progressThread;
//More Code...
progress.show();
progress.setMax(auxMobile.size() + auxStatic.size() );
progress.setProgress(0);
progressThread = new Thread(new Runnable() {
#Override
public void run() {
try {
synchronized (flag) {
while (progress.getProgress() < progress.getMax()) {
progress.incrementProgressBy(1);
flag.wait();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
progressThread.start();
try {
for(int i=0; i<auxStatic.size(); i++) {
//More Code...
flag.notify();
}
for(int i=0; i<auxMobile.size(); i++){
//More Code...
flag.notify();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
You really should use AsyncTask in that case.
Check this, this.
It's gonna make your dev life for that case a hell lot easier !