我在网上搜索了很多关于如何在Android上实时更新UI的内容,但都无济于事。我像大多数其他帖子建议的那样实现了AysncTask类,但它仍然没有像我想的那样实时更新我的UI。它只在程序完成运行后更新。我甚至收到了"跳过n帧"的提示。应用程序可能在其主线程中做了太多工作"错误,我不理解,因为我试图在UI线程中进行这些更新。运行我的程序大约5秒后,屏幕就变黑了,一直这样,直到程序完成。任何帮助将是非常感激的,因为我一直在拉我的头发在这个一段时间,这是我的代码。
编辑:解决。从我的UI线程中删除了thread .sleep(n),并将其添加到我的AsyncTask中。谢谢大家!
主类:
public class Home extends Activity {
// Declare objects
Button turingB, socratesB, voltaireB, descartesB, platoB;
int[] eating, thinking, hungry;
Philosopher socrates, turing, voltaire, descartes, plato;
Philosopher[] philosophers;
Chopstick[] chopsticks;
TextView info;
String value;
Context context;
int toastLength;
boolean turingHungry, socratesHungry, voltaireHungry, descartesHungry, platoHungry;
String running;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
// Instantiate objects (keep track of each button individually
context = getApplicationContext();
toastLength = Toast.LENGTH_SHORT;
info = (TextView) findViewById(R.id.textView1);
info.setText("Click Start to begin!");
socratesB = (Button) findViewById(R.id.button1);
descartesB = (Button) findViewById(R.id.button5);
platoB = (Button) findViewById(R.id.button4);
voltaireB = (Button) findViewById(R.id.button3);
turingB = (Button) findViewById(R.id.button2);
running = "false";
// Set all philosophers to thinking (blue)
// socratesB.setBackgroundColor(Color.BLUE);
// descartesB.setBackgroundColor(Color.BLUE);
// platoB.setBackgroundColor(Color.BLUE);
// voltaireB.setBackgroundColor(Color.BLUE);
// turingB.setBackgroundColor(Color.BLUE);
turingHungry = false;
socratesHungry = false;
voltaireHungry = false;
descartesHungry = false;
platoHungry = false;
//Button platoTempButton = (Button) findViewById(R.id.button4);
// Listen for buttons
OnClickListener pBtn = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
platoHungry = true;
}
};
//platoTempButton.setOnClickListener(pBtn);
OnClickListener tBtn = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
turingHungry = true;
}
};
OnClickListener sBtn = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
socratesHungry = true;
}
};
OnClickListener vBtn = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
voltaireHungry = true;
}
};
OnClickListener dBtn = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
descartesHungry = true;
}
};
platoB.setOnClickListener(pBtn);
turingB.setOnClickListener(tBtn);
socratesB.setOnClickListener(sBtn);
voltaireB.setOnClickListener(vBtn);
descartesB.setOnClickListener(dBtn);
// Set arrays to count time spent eating, thinking, hungry
eating = new int[5];
thinking = new int[5];
hungry = new int[5];
// Create the chopsticks
chopsticks = new Chopstick[5];
for (int i = 0; i < 5; i ++)
{
chopsticks[i] = new Chopstick(i);
}
for (Chopstick chop: chopsticks)
{
chop.available = true;
}
// Create the philosophers
philosophers = new Philosopher[5];
philosophers[0] = new Philosopher(0, chopsticks[0], chopsticks[1], "Plato", platoB);
philosophers[1] = new Philosopher(1, chopsticks[1], chopsticks[2], "Turing", turingB);
philosophers[2] = new Philosopher(2, chopsticks[2], chopsticks[3], "Socrates", socratesB);
philosophers[3] = new Philosopher(3, chopsticks[3], chopsticks[4], "Voltaire", voltaireB);
philosophers[4] = new Philosopher(4, chopsticks[4], chopsticks[0], "Descartes", descartesB);
// Get sim time from user
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Simulation Time");
alert.setMessage("Please length of time for the simulation to run (in seconds)");
final EditText input = new EditText(this);
alert.setView(input);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
value = String.valueOf(input.getText());
}
});
alert.show();
// Get info
Bundle extras = getIntent().getExtras();
if (extras != null)
{
running = extras.getString("runApp");
value = extras.getString("numToRun");
}
// Run app
if (running.equals("true"))
{
System.out.println("RUNNING!!!");
run(value);
}
}
public void run(String length)
{
int num = Integer.parseInt(length);
// Run num times
for (int i = 0; i < num; i++)
{
try {
// Pass current index, and data arrays to step method
step(i, eating, thinking, hungry);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Print out some data
for (int j = 0; j < 5; j++)
{
System.out.println("Philosopher " + j + " ate: " + eating[j]);
System.out.println("Philosopher " + j + " thought: " + thinking[j]);
System.out.println("Philosopher " + j + " was hungry: " + hungry[j]);
}
running = "false";
}
// Run simulation n times (n specified by the user)
public void startSim(View v)
{
Intent my_intent = new Intent(this, Home.class);
my_intent.putExtra("runApp", "true");
my_intent.putExtra("numToRun", value);
startActivity(my_intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.home, menu);
return true;
}
// Reset simulation
public void reset(View v)
{
Intent my_intent = new Intent(this, Home.class);
startActivity(my_intent);
}
// Return hunger status of philosopher
public boolean isHungry(String name) {
if (name.equals("Voltaire"))
return voltaireHungry;
else if (name.equals("Socrates"))
return socratesHungry;
else if (name.equals("Plato"))
return platoHungry;
else if (name.equals("Turing"))
return turingHungry;
else if (name.equals("Descartes"))
return descartesHungry;
else
return false;
}
// Step method for simulation
// Takes the current index and each of the data arrays
public void step(int i, int[] eating, int[] thinking, int[] hungry) throws InterruptedException
{
// Make random number
Random randomGenerator = new Random();
int num = randomGenerator.nextInt(10);
// Randomly set a philosopher isFull to false (hungry) (10% chance for each to become hungry if not specified by the user)
if (isHungry(philosophers[0].name))
philosophers[0].isFull = false;
if (num == 1 || isHungry(philosophers[1].name))
philosophers[1].isFull = false;
if (num == 2 || isHungry(philosophers[2].name))
philosophers[2].isFull = false;
if (num == 3 || isHungry(philosophers[3].name))
philosophers[3].isFull = false;
if (num == 4 || isHungry(philosophers[4].name))
philosophers[4].isFull = false;
// For each philosopher
for (Philosopher phil: philosophers)
{
// Print current info
System.out.println("PHIL: " + phil.name + " NUM: " + num + " RIGHT: " + phil.rightChopstick.available + " LEFT: " + phil.leftChopstick.available);
// Temp id var
int tempId = phil.id;
// If philosopher is hungry, try to eat
if (phil.isFull == false)
{
// Try to eat only if both chopsticks are available
if (phil.rightChopstick.pickUp(phil.name) && phil.leftChopstick.pickUp(phil.name))
{
// Change button color
new Background(phil.button).execute((long) 1);
//Toast.makeText(context, phil.name + " is eating.", toastLength).show();
// Increment time spent eating
eating[tempId]++;
}
// Check to see if the philosopher is already eating (has both chopsticks)
else if (phil.rightChopstick.who.equals(phil.name) && phil.leftChopstick.who.equals(phil.name))
{
//Toast.makeText(context, phil.name + " is eating.", toastLength).show();
new Background(phil.button).execute((long) 1);
// Increment eating
eating[tempId]++;
// 30% chance to stop eating
if (num >= 5 && num <=7)
{
// Put down chopsticks
phil.rightChopstick.putDown();
phil.leftChopstick.putDown();
// Stop eating
phil.isFull = true;
}
}
// Hungry
else
{
// Change button color
new Background(phil.button).execute((long) 3);
//Toast.makeText(context, phil.name + " is hungry.", toastLength).show();
// Increment time spent hungry
hungry[tempId]++;
}
}
// Thinking
else
{
new Background(phil.button).execute((long) 2);
//Toast.makeText(context, phil.name + " is thinking.", toastLength).show();
// Increment time spent thinking
thinking[tempId]++;
}
Thread.sleep(1000);
}
// Make each step count as 1 second (1000 miliseconds)
System.out.println("--------------------------------------------------------------");
Thread.sleep(5000);
}
}
后台类(AsyncTask):public class Background extends AsyncTask<Long, Void, Void>
{
// Variables
String color;
Button button;
public Background(Button button)
{
this.button = button;
}
@Override
protected Void doInBackground(Long... params) {
// Get which color the button needs to be
try
{
// Change the color based on the value passed in
if (params[0] == 3)
{
color = "RED";
}
else if (params[0] == 2)
{
color = "BLUE";
}
else if (params[0] == 1)
{
color = "GREEN";
}
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
// Set button to that color
System.out.println("Updating color in real time...");
button.setBackgroundColor(Color.parseColor(color));
}
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Void... values) {
}
}
这里有一个问题
Thread.sleep(1000);
这是另一个
Thread.sleep(5000);
这些都使UI
睡眠总共6秒。你几乎永远不想在UI Thread
上调用sleep()
。你可以在doInBackground()
或其他任何在Thread
背景上运行的地方这样做。
编辑
你没有设置Listeners
。例如:
platoB.setOnClickListener(new pBtn());
Progress可以在你的asynctask中设置publishProgress,你可以在UI线程中调用onProgressUpdate