UI不更新在Android使用AsyncTask



我在网上搜索了很多关于如何在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

相关内容

  • 没有找到相关文章

最新更新