简体   繁体   中英

TextView output in real time

Hello I have a android app which basically has a EditText to get userinput, TextView to output the processed data and a button to excute everything. Once the user click a button and new thread is made and the following two loops are running and appending the new output each time to the TextView. However what the problem the TextView output isnt going to the TextView in real time when the loops are finished its displays all the outputted data at once, help please .

package com.example.assignment2_android;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class station extends Activity 
{
    Button run, clear, home;
    EditText userinput;
    TextView useroutput;

    //LinkedList Customer Queue created here.
    public static Queue<String> line = new  LinkedList<String> (); 
    private static String time;   //time variable.
    private static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");   //DateFormat variable.

    private int intervals;
    private int cashiers;
    private int processing_time;
    Thread arrival;
    Handler handler, handlerr, handlerrr;

    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.station);

        userinput = (EditText)findViewById(R.id.s_userinput);
        useroutput = (TextView)findViewById(R.id.s_useroutput);

        clear = (Button)findViewById(R.id.button_clear);
        clear.setOnClickListener(new View.OnClickListener() 
        {
              public void onClick(View view) 
              {
                  line.clear();
                  userinput.setText("Line Cleared");
                  useroutput.setText("");
                  System.out.println("cleared");
              }
        });

        home = (Button)findViewById(R.id.button_home);
        home.setOnClickListener(new View.OnClickListener() 
        {
              public void onClick(View view) 
              {
                  Intent a = new Intent(station.this, MainActivity.class);
                  startActivity(a);
              }
        });
    }

    public void startProgress(View view)
    {
        handler = new Handler();
        Thread arrival = new Thread();
        {
            useroutput.append("CUSTOMERS ARE COMING !!!! !!!!" + "\n" + "\n");;
            //Array of all the customer that will enter the queue.
            String list[] = {"Naqi", "Monty", "Mohin", "Yasmin", "Maighjoo", "Ashish", "Paal", "Kevin", "Ruhail", "Tony"};
            //2nd ArrayList which customer are added to and removed later on so no duplicates arise.
            ArrayList<String> customer = new ArrayList<String>(Arrays.asList(list));

            int array_customer_list = list.length; //Recording the number of customers in the array.

            //While statement containing for loop add customers to the empty LinkedList object.
            while (line.isEmpty())
            {
                for (int x = 0; x < array_customer_list; x++ )
                {
                    try
                    {
                        Thread.sleep(ran_interval() * 1000);   //Sleep method to hold the arrival time by 1-2 seconds. 
                        int cus = (int) (Math.random() * customer.size());   //Random customer is picked here. 
                        String new_cus = customer.get(cus);   //New customer object is created ere.
                        line.add(new_cus);   //Customer objects are added to the empty LinkedList queue.
                        customer.remove(cus);

                        //For loop statement to outputting the queue.
                        for (String s : line)
                        {
                            useroutput.append("[" + s.toString() + " " + "]" + "\n");; //Outputting each customer and using the ".name" method so customers are readable.
                        }
                        //Outputting the whole queue and stating who has joined the queue.
                        useroutput.append("\n" + "The queue has " + line.size() + " customers so far" + "\n" + 
                        new_cus.toString() + " Has Joined the Queue " + " <=== WAITING" + "\n" + "\n");
                    }
                    catch(Exception a)   //ERROR handler for sleep method.
                    {
                        System.out.println("Intervals error: " + a);   //Outputting the ERROR message.
                        System.exit(0);   //If ERROR found exit system.
                    }

                }
            }
            userinput.append("\n");
            useroutput.append("CUSTOMERS ARE WAITING !!!! !!!!" + "\n" + "\n");
            useroutput.append("Processing START !!!!" + "\n" + "\n");

            while (!line.isEmpty())   //While statement with for loop to remove each customer from LinkedList queue.
            {
                try 
                {
                    String cus = line.remove(); //Method to remove customer from LinkedList queue.
                    String time = getTime();
                    Thread.sleep((processing_time() * 1000) / cashiers); //Sleep method to hold the processing by 1-3 seconds.
                    for (String s : line)
                    {
                        useroutput.append("[" + s.toString() + " " + "]" + "\n"); //Outputting each customer and using the ".name" method so customers are readable.
                    }
                    //Outputting the whole queue and stating who has joined the queue.
                    useroutput.append("\n" + "The queue has " + line.size() + " customers left" + "\n" + 
                    cus.toString()+ " waited for " + time + " <=== SERVED" + "\n" + "\n");
                }
                catch(Exception a)   //ERROR handler for sleep method.
                {
                    System.out.println("Cashiers_wait error: " + a);   //Outputting the ERROR message.
                    System.exit(0);   //If ERROR found exit system.
                }
            }
            useroutput.append("Processing FINISHED !!!!" + "\n");
            System.out.println("working" + "\n" + "random arrival time is :" + intervals + "\n" + 
            "random processing time is :" + processing_time);
        }; arrival.start();
    };

    public void append_output(final String text)
    {
        runOnUiThread(new Runnable()
        {
            @Override
            public void run() 
            {

                useroutput.append(text);
            }
        });
    }

    static String getTime()   //Time Constructor
    {
       Calendar cal = Calendar.getInstance();
       time = dateFormat.format(cal.getTime());   //Getting the current system time.
       return time;   //Return time.
    }

    public int ran_interval()
     {
         Random rand = new Random(); //Random object created here.
         int interval = this.intervals = rand.nextInt(2) + 1; //Random number between 1-2 is generated for customer arrival here.

         return interval;
     }

    public int processing_time()
     {
         Random ran = new Random();    //Random object created here.
         int time = this.processing_time = ran.nextInt(4) + 1;  //Random number between 1-3 is generated for customer arrival here.

         return time;
     }
}

It looks like your problem is that you're trying to update the UI from a thread not meant to do so. You made the function append_output seemingly for this purpose, but then never used it. Since your arrival thread isn't running on the UI, it can't update the textbox in real time. So basically, instead of having a bunch of useroutput.append s in your arrival thread, change them all to append_output(text) , and that SHOULD fix your problems.

First organize your import and respect android coding style. I correct the beggining of your code.

private static Button mRun, mClear, mHome;
private static EditText mUserInput;
private static TextView mUserOutput;

//LinkedList Customer Queue created here.
public static Queue<String> line = new  LinkedList<String> ();
private static String time;   //time variable.
private static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");   //DateFormat variable.

private int intervals;
private int cashiers;
private int processing_time;
Thread arrival;
Handler handler, handlerr, handlerrr;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.station);

    mClear = (Button)findViewById(R.id.button_clear);
    mHome = (Button) findViewById(R.id.button_home);
    mUserInput = (EditText) findViewById(R.id.s_userinput);
    mUserOutput = (TextView) findViewById(R.id.s_useroutput);

    if (mClear != null) {
        mClear.setOnClickListener(this);
    }

    if (mHome != null) {
        mHome.setOnClickListener(this);
    }
}

public void onClick(View view) {
    if (view == mClear) {
        line.clear();
        mUserInput.setText(getString(R.string.line_cleared)); //Use string ressource !
        mUserOutput.setText("");
        System.out.println("cleared"); // Use string ressource
    } else if (view == mHome) {
        Intent a = new Intent(this, MainActivity.class);
        startActivity(a);
    }
}

You have to use thread to do some complex calcul, get your data. But the initialization of a user interface can't be done in a worker thread. You have to be on the main thread. As usual everything is here : http://developer.android.com/guide/components/processes-and-threads.html

Really though, you should be using AsyncTask to be handling your UI updates. Do something like:

 private class updateTextView extends AsyncTask<String, String, Void> {
  protected void doInBackground(String text) {
      publishProgress(text)
  }
  protected void onProgressUpdate(String text)
  {
      useroutput.append(text)
  }
 }

above your class declaration.

Then every time you want to update your textview, you just do

new updateTextView().execute(text)

I'm not sure on the exact syntax of these, as I'm not at a computer with the Android SDK installed and such, but that should at least get you far enough along that your IDE should be able to handle the rest. While this might be sloppy or "poor form," it should get things working for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM