Hello guys I want to place the following code in a new thread that is different from the ui thread but android studio gives an error that the variable needs to be declared final. when i declare the variable final it crashes my app. Please how can i start a new thread without declaring the variable final.
public void checkUpTaking(int position, int rowImpact, int takenPawn) { //taken pawn: -1 = brown, 1 = white
if (position > 10) { //if you'll try to take from the last row - array out of bounds
if (position % 5 != 0 && playableTile[position - 1 - 4 - rowImpact].getIsTaken() == takenPawn &&
playableTile[position - 1 - 9].getIsTaken() == 0) {
checkTreeNodes(position, position - 9, position-4-rowImpact); //checking possible mandatory moves before clicking pawn
}
if ((position - 1) % 5 != 0 && playableTile[position - 1 - 5 - rowImpact].getIsTaken() == takenPawn &&
playableTile[position - 1 - 11].getIsTaken() == 0) {
checkTreeNodes(position, position - 11, position-5-rowImpact);
}
}
}
I am trying to achieve something like this without make my variable final
public void checkUpTaking(int position, int rowImpact, int takenPawn) { //taken pawn: -1 = brown, 1 = white
new Thread(new Runnable() {
@Override
public void run() {
if (position > 10) { //if you'll try to take from the last row - array out of bounds
if (position % 5 != 0 && playableTile[position - 1 - 4 - rowImpact].getIsTaken() == takenPawn &&
playableTile[position - 1 - 9].getIsTaken() == 0) {
checkTreeNodes(position, position - 9, position-4-rowImpact); //checking possible mandatory moves before clicking pawn
}
if ((position - 1) % 5 != 0 && playableTile[position - 1 - 5 - rowImpact].getIsTaken() == takenPawn &&
playableTile[position - 1 - 11].getIsTaken() == 0) {
checkTreeNodes(position, position - 11, position-5-rowImpact);
}
}
}
}).start();
}
2
Answers
You don’t have to make position, rowImpact, or takenPawn final.
But you can’t change it before your new Thread(new Runnable()..
If you have to it has to be final.. why? here is a detailed description: https://blog.brendanlacanette.com/2015/08/variable-is-accessed-within-inner-class.html
To solve this you have some possibilities:
make a new final variable, and use this in your Runnable
final int finalPosition = position;
put them in an array, and use for example params[0] in your Runnable.
I don’t like this approach
int[] params = new int[]{position, rowImpact, takenPawn};
create a wrapper object for your parameters
The code you’ve shown here doesn’t require
final
, at least when compiling in Java 8+, which allows anonymous classes to reference effectively-final variables.The only reason you wouldn’t be able to reference the parameters inside the anonymous class is if there is code which reassigns them (either inside or outside the anonymous class): without reassignment, the parameters would be considered effectively final.
If there is other code in this method which reassigns these variables, the simple answer is to extract either the code you’ve shown or the code you’ve not into another method:
Or you can declare extra variables with the same values as the parameters, and reference these inside the thread:
Or you can declare the
Runnable
with a named class, and give it a constructor and explicit fields: