使用延迟处理闪光灯的亮灭,关于looper的使用

今天帮一个同学做一个东西,要求在手机上输入1和0控制手机闪关灯的亮灭。开始以为很简单,仔细一想,还是有点意思的(当然对于大牛来说这都不是事!),简单的布局,这里就贴代码了,直接上效果图这里写图片描述
oncreate方法里面也是很简单

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button);
         editText=(EditText) findViewById(R.id.edittext);
        button.setOnClickListener(new ButtonOnClick());
        context = this;
    }

这里通过camera控制闪光灯,当然这是比较古老的方法,也有其他的方法,

这里写了个内部类,更方便的实现对闪光灯的控制,,这部分代码不是我写的,其他人写好了,我只写了后面的控制逻辑

class ControlFlash {
        public Camera camera;
        public Camera.Parameters parameters;

        public ControlFlash() {
            camera = Camera.open();
            parameters = camera.getParameters();
        }

        public void open() {
            parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
            camera.setParameters(parameters);
            camera.startPreview();
        }

        public void close() {
            parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
            camera.setParameters(parameters);
            camera.stopPreview();
        }
    }

重点看一下ButtonOnClick里面的代码

private final class ButtonOnClick implements View.OnClickListener {

        ControlFlash cf = new ControlFlash();

        public void onClick(View v) {
            // TODO Auto-generated method stub

            new Thread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub

              String string=editText.getText().toString();
             char[] myinput=!TextUtils.isEmpty(string)?string.toCharArray():input;

                    for (char a : myinput) {
                        if (a == '1') {
                            new Handler(context.getMainLooper()).postDelayed(
                                    new Runnable() {

                                        @Override
                                        public void run() {
                                            // TODO Auto-generated method stub
                       Log.e("mythread", Thread.currentThread().getName());
                                            cf.open();
                                            new Handler(context.getMainLooper())
                                                    .postDelayed(
                                                            new Runnable() {

                                                                @Override
                                                                public void run() {
                                                                    // TODO
                                                                    // Auto-generated
                                                                    // method
                                                                    // stub
                                                                    cf.close();
                                                                }
                                                            }, 20);

                                        }
                                    }, 50);

                        }
                        try {
                            Thread.currentThread().sleep(100);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }).start();

        }
    }

首先拿到一个ControlFlash的对象,这里我习惯在子线程里面做一些其他的事。在run方法中首先拿到输入的字符,判断一下,很简单,input是已经赋值的一个char数组,这里使用Handler的postDelayed方法来处理延时操作,,(如果直接循环判断每个字符的话,运行时间极短,手机根本来不及反应,这里可以了解一下手机闪光灯的原理),,,当然延迟操作还可以使用线程,或者延时器都行,本例中使用postDelayed的方法,,,可以看到我们在new Handler的时候,传入了context.getMainLooper(),context就是activity实例,,,就是让下面run方法中的代码在主线程的消息队列处理(Looper.getMianLoooper也是一样的),,,,这里不知道为啥在new Handler之前使用Looper.perare();的时候,run里面的代码就不执行,,,懂得朋友告诉我哦,,,这里为什么这样做呢,,这里我们是在子线程中处理这些逻辑,而子线程中需要自己去添加消息队列(主线程中系统会处理好),,这里由于Looper.perare试了不知道啥原因不行,所以就添加到主线程的消息队列中,,打印出来的日志,,可以看到确实在主线程里面

下面可能有些朋友会问为啥要让线程sleep0.1秒,,因为我们让打开闪光灯的操作和关闭操作分别延时0.05和0.02秒(这两个值是随手设置的,,)如果没有sleep,,可以想象一下,打开和延迟由于有时间差,就不会成对的交替起作用,这样很可能会导致灯闪的很乱,,,sleep0.1秒让前次的打开关闭操作已经完成,,,这样就OK了,,(本人新手,对looper以及消息处理机制还没有透彻理解,有错的地方还请指出)

高能!!!
刚刚那个人说哦要的不是这样的。。,是这样的

                public void run() {
                    // TODO Auto-generated method stub

                    String string = editText.getText().toString();
                    char[] myinput = !TextUtils.isEmpty(string) ? string
                            .toCharArray() : input;

                    for (char a : myinput) {
                        if (a == '1') {
                            cf.open();
//                          new Handler(context.getMainLooper()).postDelayed(
//                                  new Runnable() {
//
//                                      @Override
//                                      public void run() {
//                                          // TODO Auto-generated method stub
//                                          Log.e("mythread", Thread
//                                                  .currentThread().getName());
//                                          cf.open();
//
//                                      }
//                                  }, 50);

                        } else {
                            cf.close();
//                          new Handler(context.getMainLooper())
//                          .postDelayed(
//                                  new Runnable() {
//
//                                      @Override
//                                      public void run() {
//                                          // TODO
//                                          // Auto-generated
//                                          // method
//                                          // stub
//                                          cf.close();
//                                      }
//                                  }, 20);
                        }
                        try {
                            Thread.currentThread().sleep(100);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }).start();

一行代码,,,我晕,他需要的是1的时候一直亮,而不是闪一下,,,(模拟信号和离散信号吧,,哈哈)。。。伙伴们以后要注意一定要与委托方交流好再动手!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值