首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >postDelayed阻塞ui线程

postDelayed阻塞ui线程
EN

Stack Overflow用户
提问于 2015-01-28 20:10:31
回答 3查看 6.1K关注 0票数 3

我想要的:用户保持按下1900 The的按钮。如果他在1900 his前拿起手指,手机就会停止振动。当他将手指按在按钮上超过1900秒时,计算()方法就会运行。--我正在使用:postDelayed --当我读到它时,它不会干扰ui线程。我正在试着检查1900秒是否已经过去了,用户还没有选择他的手指,甚至连计算方法都没有运行。错误发生在g中:如果用户在1900秒前抓到手指,或者只是触碰并立即抓取,手机就会继续震动。虽然它不应该发生,因为我正在检查它与MotionEvent.ACTION_UP。救命啊!!

代码语言:javascript
复制
  int flag = 0;
  int aborted_flag = 0;
 @Override
public boolean onTouch(View v, MotionEvent event) {

    Handler mHandler = new Handler();

    if(event.getAction()==MotionEvent.ACTION_DOWN){
        scanning();
        t1 = System.currentTimeMillis();
        vibrator.vibrate(1900);

        mHandler.postDelayed(new Runnable() {
            public void run() {
               check();
            }
        }, 1901);
    }

    if(event.getAction()==MotionEvent.ACTION_UP){
        if(flag == 0){
            t2 = System.currentTimeMillis();
            vibrator.cancel();
            calculate();
            aborted_flag = 1;
        }
    }

    return true;
}

private void check() {
    t2 = System.currentTimeMillis();
    Log.e("Hello","Inside Check");
    Log.e("Hello",""+aborted_flag);
    vibrator.cancel();
    if(aborted_flag==0){
        calculate();
        flag = 1;
    }
}

private void scanning() {
    textView.setText("Scanning");
}

private void calculate() {
    Log.e("t2-t1 ", t2-t1+"");

    if(t2-t1>=1900){
        Random r = new Random();
        int k = r.nextInt((5 - 0) + 1) + 0;
        textView.setText(str[k]);

        ////////////animation library code/////////////
        YoYo.with(Techniques.StandUp)
                .duration(700)
                .playOn(findViewById(R.id.text_view));
        ////////////////////////////////////////

        changeBackgroundColor(k);

        //textView.setTextColor(Color.parseColor("#00ff00"));
         flag = 0;
    }
    else{
        textView.setText("Aborted\n Try Again");
        relativeLayout.setBackgroundResource(R.color.red);
    }
}
public void changeBackgroundColor(final int k) {
    runOnUiThread(new Runnable(){
        public void run() {
            switch(k){
                case 0: relativeLayout.setBackgroundResource(R.color.blue);
                    break;
                case 1: relativeLayout.setBackgroundResource(R.color.pink);
                    break;
                case 2:;
                case 3: relativeLayout.setBackgroundResource(R.color.green);
                    break;
                default:relativeLayout.setBackgroundResource(R.color.yellow);
            }
        }
    });
}
EN

回答 3

Stack Overflow用户

发布于 2015-01-28 20:48:49

如果您从UI线程调用postDelayed,那么您的代码将在UI线程上执行。

若要使用不同的线程,请创建一个:

代码语言:javascript
复制
Thread t = new Thread(new Runnable(){});
t.start();
票数 5
EN

Stack Overflow用户

发布于 2019-05-29 07:06:10

您可以创建一个HandlerThread,并使用它的looper创建一个处理程序,然后向它发布postpostdelayed的内容

代码语言:javascript
复制
public class myActivity extends Activity
{
    private HandlerThread loaderThread;
    private Handler loader;

    @override
    public void onResume()
    {
        super.onResume();

        if (loaderThread == null)
        {
            loaderThread = new HandlerThread("MyActivitySeparateThread");
            loaderThread.start();
            loader = new Handler(loaderThread.getLooper());
        }
    }

    @override
    public void onDestroy()
    {
        //Stop and release handler
        try {
            loader.removeCallbacksAndMessages(null);
            loader.dispose();
        } finally {
            loader = null;
        }

        //Stop and release Thread
        try {
            loaderThread.quit();
            loaderThread.dispose();
        } finally {
            loaderThread = null;
        }

        super.onDestroy();
    }

    @Override
    public boolean onTouch(View v, MotionEvent event)
    {
        switch(event.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                {
                    scanning();
                    t1 = System.currentTimeMillis();
                    vibrator.vibrate(1900);

                    loader.postDelayed(new Runnable()
                    {
                        public void run()
                        {
                            check();
                        }
                    }, 1901);
                    break;
                }
            case MotionEvent.ACTION_UP:
                {
                    if (flag == 0)
                    {
                        t2 = System.currentTimeMillis();
                        vibrator.cancel();
                        calculate();
                        aborted_flag = 1;
                    }
                    break;
                }
        }

        return true;
    }
}
票数 1
EN

Stack Overflow用户

发布于 2015-01-28 20:22:19

因为在mHandler.postDelayed中,您可以调用check(),后者调用relativeLayout.setBackgroundResource()。用户界面只能从UIThread中更改。

使功能:

代码语言:javascript
复制
public void changeBackgroundColor(final int color) {
   runOnUiThread(new Runnable(){
        public void run() {
           relativeLayout.setBackgroundResource(color);
          }
    });
}

并从计算()函数调用它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28201461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档