2

我有一个与后端 Web 服务对话的 Androd 应用程序。作为测试的一部分,我需要在按下提交按钮时模拟不同长度的客户端延迟。

现在,我在我的 OnClickListener 中使用 Thread.sleep() 作为我的提交按钮,但是像这样休眠 UI 线程会导致应用程序看起来完全“冻结”的意外后果 - 按钮一直突出显示直到线程醒来,我的 ProgressBar 同样完全冻结。这是我的代码:

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();
        }
    });  
}

我正在寻找可以在不挂起整个 UI 的情况下模拟延迟的方法。欢迎任何想法。谢谢!

编辑

这里有一些澄清!我需要做的一部分是模拟延迟并允许用户界面干净地处理它(这是现在没有发生的事情)。

即...如果客户端或 Web 服务出现延迟,客户端应通过在等待时让微调器旋转来处理它。模拟后端延迟的能力已经完成,并且可以按照我想要的方式工作,但我想在客户端模拟延迟而不挂起 UI 线程。

4

3 回答 3

4

开始了:

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();
        }
    });  
}

因此,您正在 onClick 事件中启动一个新线程。这个新线程应该在休眠 3 秒后完成应用程序的工作。之后,您想要更新一些 ui 对象,并且您不能从不是 UI 线程的线程中执行此操作。这就是为什么在执行工作之后会有一个 runOnUiThread(..) 的原因。希望能帮助到你!

于 2012-10-16T14:49:45.120 回答
3

首先,不要阻塞主线程(ui-thread),否则gui会被冻结!相反,使用AsyncTask, 你放在Thread.sleep(3000)里面的地方doInBackground(),然后在里面做任何你想做的事情onPostExecute()onPostExecute()在主线程中运行)。检查对相关问题的最后回答。

于 2012-10-16T14:45:28.887 回答
0

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.

于 2012-10-16T14:47:24.390 回答