简短的故事:
我需要将一些代码从我的 UI 线程中移出到后台线程中,并且我需要能够将五个变量值传递到该后台线程并从中接收五个值。我希望有人可以提供一个简单的工作示例,假设下面的代码是我的代码,而注释行之间的位是需要移动的。
更长的故事:
我的 UI 线程中的部分代码需要大约 15 秒才能完成。在此期间屏幕冻结。我不介意屏幕冻结,因为用户此时不需要与屏幕交互。问题是我也有一个OnKeyListener在我的 UI 线程中,它不赞成延迟。如果用户在 15 秒延迟期间按下任何键盘键,将导致大约 5 秒后出现 ANR(应用程序无响应)提示。我需要将耗时的代码移到可以在后台运行的单独线程中。我花了大约 13 个小时试图弄清楚如何使用 AsyncTask 和其他方法来做到这一点,但无法弄清楚如何将五个变量值传递到线程中并从中接收五个值。我希望有人可以提供一个简单的工作示例,假设下面的代码是我的代码,而注释行之间的位是需要移动的。
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);
}
});
编辑:
这是我最终为解决这个问题所做的事情:
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;
}
}