简体   繁体   中英

How to simulate client-side delay on Android without hanging the UI?

I have an Androd application that talks to a back-end web service. As part of the testing, I need to simulate different lengths of client-side delay when a submit button is pressed.

Right now, I am using a Thread.sleep() in my OnClickListener for my submit button, but sleeping the UI thread like this has the unintended consequence of causing the app to appear to "freeze" completely - the button stays highlighted until the thread wakes up and my ProgressBar is likewise completely frozen. Here is my code:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_checkout);

    pBar = (ProgressBar) findViewById(R.id.progressBar1);
    pBar.setVisibility(View.INVISIBLE);

    Button submitButton = (Button) findViewById(R.id.btnSubmit);
    submitButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            pBar.setVisibility(View.VISIBLE);
            try {
                Thread.sleep(3000); //eventually this delay will be random
                                    //right now it obviously hangs the UI
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            performMyAppSpecificWorkHere();
            pBar.setVisibility(View.INVISIBLE);
            CheckoutActivity.this.finish();
        }
    });  
}

I'm looking for ways I could simulate a delay without hanging the entire UI. Any ideas are welcome. Thanks!

edit

Some clarification here! Part of what I need to do is make simulate a delay and allow the user interface to handle it cleanly (which is what's NOT happening now).

ie...if there is a delay on either the client or the web service, the client should handle it by letting the spinner spin while it waits. The ability to simulate a back-end delay is already done and that works the way I want it to, but I want to simulate a delay on the client without hanging the UI thread.

here we go:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_checkout);

    pBar = (ProgressBar) findViewById(R.id.progressBar1);
    pBar.setVisibility(View.INVISIBLE);

    Button submitButton = (Button) findViewById(R.id.btnSubmit);
    submitButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            Thread t=new Thread(new Runnable(){
               @Override
               public void run(){
                 try {
                  Thread.sleep(3000);
                 } catch (InterruptedException e) {
                   e.printStackTrace();
                 }
                 performMyAppSpecificWorkHere();
                 runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        pBar.setVisibility(View.INVISIBLE);
                        CheckoutActivity.this.finish();
                    }
                 }
               }
            });
            pBar.setVisibility(View.VISIBLE);
            t.start();
        }
    });  
}

So, you are starting a new thread in the onClick event. This new thread should do the application work after sleeping for 3 seconds. After that, you want to update some ui objects, and you can not do that from inside a thread that isn't the UI Thread. That's why there is a runOnUiThread(..) after performing the work. Hope it helps!

First of all, don't block the main thread (the ui-thread), or else the gui will be freezed! Instead, use AsyncTask , where you put Thread.sleep(3000) inside doInBackground() , and then do whatever you want inside onPostExecute() ( onPostExecute() is running in the main thread). Check my last answer on related question.

I think you should clarify here, you want to simulate server side delays and not the client side delay. You should put the sleep code in your server side code and not the client side code.

If it is not so, you can use asyncTask and execute the application code. You can put the sleep code inside it to simulate a client side delay.

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