Short story:
I need to move a bit of code out of my UI thread and into a background thread, and I need to be able to pass five variable values into that background thread and receive five values back from it. I'm hoping someone can provide a simple working example, pretending that the code below is my code and the bit between the commented lines is what needs to be moved.
Longer story:
Part of the code in my UI thread is taking about fifteen seconds to complete. The screen freezes during this period. I don't mind that the screen freezes because the user doesn't need to interact with the screen at that point anyway. The problem is that I also have an OnKeyListener in my UI thread and it doesn't approve of the delay. If the user presses any keyboard key during the fifteen-second delay, it will cause an ANR (application not responding) prompt to appear about five seconds later. I need to move the time-consuming code into a separate thread where it can run in the background. I've spent about thirteen hours trying to figure out how to do this using AsyncTask and other methods but have been unable to figure out how to pass five variable values into the thread and receive five values back from it. I'm hoping someone can provide a simple working example, pretending that the code below is my code and the bit between the commented lines is what needs to be moved.
myButton.setOnClickListener(new OnClickListener()
{
public void onClick(View arg0)
{
Integer userNum1 = 12; //pretend these numbers are user inputted (ever-changing)
Integer userNum2 = 8;
Integer userNum3 = 2;
Integer userNum4 = 31;
Integer userNum5 = 17;
Integer userMultiplier = 9;
//-----------------------------
for (int i = 0; i < 15; i++)
{
userNum1 = userNum1 * userMultiplier;
userNum2 = userNum2 * userMultiplier;
userNum3 = userNum3 * userMultiplier;
userNum4 = userNum4 * userMultiplier;
userNum5 = userNum5 * userMultiplier;
try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}
}
//-----------------------------
String myString1 = String.valueOf(userNum1);
String myString2 = String.valueOf(userNum2);
String myString3 = String.valueOf(userNum3);
String myString4 = String.valueOf(userNum4);
String myString5 = String.valueOf(userNum5);
}
});
EDIT:
Here's what I ended up doing to solve this problem:
public Integer myTaskDone = 0;
public Integer userNum1 = 0;
public Integer userNum2 = 0;
public Integer userNum3 = 0;
public Integer userNum4 = 0;
public Integer userNum5 = 0;
public Integer userMultiplier = 0;
public String[] valueTransporter = new String[20];
myButton.setOnClickListener(new OnClickListener()
{
public void onClick(View arg0)
{
userNum1 = 12;
userNum2 = 8;
userNum3 = 2;
userNum4 = 31;
userNum5 = 17;
userMultiplier = 9;
valueTransporter[0] = String.valueOf(userNum1);
valueTransporter[1] = String.valueOf(userNum2);
valueTransporter[2] = String.valueOf(userNum3);
valueTransporter[3] = String.valueOf(userNum4);
valueTransporter[4] = String.valueOf(userNum5);
valueTransporter[5] = String.valueOf(userMultiplier);
new myTask().execute(valueTransporter);
}
});
//Had to move the last section of code into this new thread, otherwise the code would have executed before myTask finished.
//All this thread does is frequently check myTaskDone to see if it equals 1 (if it does equal 1, the last section of code will be executed).
final Handler mHandler = new Handler();
new Thread(new Runnable()
{
@Override
public void run()
{
while (true)
{
try
{
Thread.sleep(10);
mHandler.post(new Runnable()
{
@Override
public void run()
{
if (myTaskDone == 1)
{
myTaskDone = 0;
String myString1 = String.valueOf(userNum1);
String myString2 = String.valueOf(userNum2);
String myString3 = String.valueOf(userNum3);
String myString4 = String.valueOf(userNum4);
String myString5 = String.valueOf(userNum5);
}
}
});
} catch (Exception e) {}
}
}
}).start();
public class myTask extends AsyncTask<String,String,String[]>
{
@Override
protected String[] doInBackground(String... valueTransporter)
{
//Our values have been transported in via valueTransporter. Put those values back into variables so we can work on them.
Integer userNum1 = Integer.parseInt(valueTransporter[0]);
Integer userNum2 = Integer.parseInt(valueTransporter[1]);
Integer userNum3 = Integer.parseInt(valueTransporter[2]);
Integer userNum4 = Integer.parseInt(valueTransporter[3]);
Integer userNum5 = Integer.parseInt(valueTransporter[4]);
Integer userMultiplier = Integer.parseInt(valueTransporter[5]);
//Do work
//-----------------------------
for (int i = 0; i < 15; i++)
{
userNum1 = userNum1 * userMultiplier;
userNum2 = userNum2 * userMultiplier;
userNum3 = userNum3 * userMultiplier;
userNum4 = userNum4 * userMultiplier;
userNum5 = userNum5 * userMultiplier;
try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}
}
//-----------------------------
//Now that the work has been done on the values, load them back into valueTransporter.
valueTransporter[0] = String.valueOf(userNum1);
valueTransporter[1] = String.valueOf(userNum2);
valueTransporter[2] = String.valueOf(userNum3);
valueTransporter[3] = String.valueOf(userNum4);
valueTransporter[4] = String.valueOf(userNum5);
return valueTransporter;
}
protected void onPostExecute(String[] valueTransporter)
{
//Get the values out of valueTransporter and into the original variables used by the UI thread.
userNum1 = Integer.parseInt(valueTransporter[0]);
userNum2 = Integer.parseInt(valueTransporter[1]);
userNum3 = Integer.parseInt(valueTransporter[2]);
userNum4 = Integer.parseInt(valueTransporter[3]);
userNum5 = Integer.parseInt(valueTransporter[4]);
myTaskDone = 1;
}
}