预定定时器阻止自身

时间:2016-10-17 13:19:52

标签: java android asynchronous timer scheduled-tasks

我已经得到了以下代码:

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        TextureView textureView = (TextureView) findViewById(R.id.texture);

        if (textureView != null) {
            try {
                Log.i("MainActivity", "Read start");
                String str = readQr(textureView.getBitmap());
                if (str != null)
                    Log.i("MainActivity", str);
                else Log.i("MainActivity", "No QR Code found.");
            } catch (NotFoundException ex) {
                Log.i("MainActivity", "No QR Code found.");
            } catch (ChecksumException | FormatException e) {
                e.printStackTrace();
            }
        }
    }
}, 0, 250);

它应该每秒检查TextureView四次的QR码。计算时间不到一秒钟。问题是,计时器只打开一个线程,它自己阻止=>任务每秒只运行一次。

根据this评论scheduleAtFixedRate应该做的诀窍......但事实并非如此,在我的情况下,它的行为与schedule完全相同。

实现我想要的最佳选择是什么?

编辑:我按照评论中的建议将ScheduledExecutorService替换为计时器,但它仍会导致完全相同的行为。

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10); // I know it's too much, I just tried using 10 Threads because 4 did still not work.
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        final TextureView textureView = (TextureView) findViewById(R.id.texture);

     if (textureView != null) {
            try {
                Log.i("MainActivity", "Read start");
                String str = readQr(textureView.getBitmap());
                if (str != null)
                    Log.i("MainActivity", str);
                else Log.i("MainActivity", "No QR Code found.");
                Log.i("MainActivity", "Read end");
            } catch (NotFoundException ex) {
                Log.i("MainActivity", "No QR Code found.");
                Log.i("MainActivity", "Read end");
            } catch (ChecksumException | FormatException e) {
                e.printStackTrace();
                Log.i("MainActivity", "Read end");
            }
        }
    }
}, 0, 250, TimeUnit.MILLISECONDS);

2 个答案:

答案 0 :(得分:0)

一个可能的解决方案是让计时器任务启动一个新线程来执行检查,所以只要新线程启动不超过0.25秒就可以跟上它。

问题是实际检查会重叠,这意味着您可能有3-4个任务同时找到QR码。那就是你想要的东西,因为它可能会有更多的并发问题。

答案 1 :(得分:0)

您想检查后台线程中的QR码并更新ui,然后您应该使用后台线程和Handler来更新UI。它可以通过多种方式完成。这是一种方式。

 public class FifthActivity extends AppCompatActivity  {

       Handler uiHandler;
        Handler backgroundHandler;
        TextView textureView;
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.collapsing_layout);
        textureView = (TextView) findViewById(R.id.textView_fifth);



            uiHandler=new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);

                    textureView.setText(msg.getData().getString("msg"));

                }
            };
            HandlerThread thread=new HandlerThread("BackgroundTask");
            thread.start();
            backgroundHandler=new Handler(thread.getLooper());


           backgroundHandler.post(new Runnable() {
                @Override
                public void run() {

                    Log.i("FifthActivity", "Read start");
                    String str = ""+ new Random().nextInt(10);
                    if (str != null) {
                        Log.i("FifthActivity", str);
                        Message message=uiHandler.obtainMessage();
                        Bundle bundle=new Bundle();
                        bundle.putString("msg",str);
                        message.setData(bundle);
                        uiHandler.sendMessage(message);
                       // textureView.setText(str);
                    }
                    else Log.i("FifthActivity", "No QR Code found.");
    backgroundHandler.postDelayed(this,250);
                }
            });

    }
    }

您也可以使用asynctask或Observer模式机制