1

所以,我做了一个手电筒应用程序......正常的手电筒功能完全正常,没有问题。

下面解释了可能导致 ANR 的以下功能说,我想通过闪烁的闪光灯发送一条 SOS 消息(摩尔斯电码)。(它的 111-000-111)所以它是 On-On-On-Off-Off-Off- 并重复。

(慢慢读)我“开”了一会儿,然后一点点闪光,再次“开”——这是为了区分两个连续的“开”……这就是我如何得到三个不同的闪光。

麻烦的是,对于时间延迟,我让线程进入睡眠状态。(这种方法对我来说效果最好)

这是我的示例函数,它会闪现 SOS:(我有一个单独的 SOS 按钮)

public void sos(View v) {

        String myString = "111000111";

        for (int x = 0; x < myString.length(); x++) {
            if (myString.charAt(x) == '1') {

                p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                c.setParameters(p);
                c.startPreview();
                flag = true;

            } else {

                p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                c.setParameters(p);
                flag = false;
            }

            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
            c.setParameters(p);
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
        c.setParameters(p);
    }

}

上面只闪出一次SOS。但是,当这种闪烁和闪烁正在进行时,我的应用程序被冻结了。闪烁的 SOS 是完美的。但它不会响应任何按钮单击,甚至不会响应中途停止它的返回按钮。

我认为这是因为线程(UI)正在休眠,因此它不关心用户在做什么)......但是点击肯定是注册的,如果根据 android 如果它没有按照规定进行照顾一段时间(我想几秒钟)......应用程序进入 ANR。

所以,我需要用我定义的间隔进行短暂的暂停(如上我使用 300 毫秒)。但我也想知道如何让应用程序同时响应按钮点击或后退按钮按下,以避免 ANR 并让用户能够随时关闭闪烁。

这个怎么做 ?

编辑 Waza_Be 的解决方案:

好的,这是我根据 Waza_Be 修改的函数。问题似乎是,它确实等待了 300 毫秒(在我的情况下)......但我有几个 postDelay 函数 - 所以我认为它实际上是将所有函数排列在一起,并且 300 毫秒的等待时间有些重叠。在此期间结束后,所有代码同时运行,使其毫无意义。

当我尝试这个时,闪光灯闪烁得相当快,而不是我想要的微妙的停顿和闪烁效果。

public void sos(View v) {
        String myString = "111000111";
        Handler handler = new Handler();

        for (int x = 0; x < myString.length(); x++) {
            if (myString.charAt(x) == '1') {
                     handler.postDelayed(new Runnable() {
                    public void run() {
                        p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                        c.setParameters(p);
                        c.startPreview();
                    }
                }, 300);

            } else {

                handler.postDelayed(new Runnable() {
                    public void run() {
                        p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                        c.setParameters(p);
                    }
                }, 300);

            }


            handler.postDelayed(new Runnable() {
                public void run() {
                    p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                    c.setParameters(p);
                }
            }, 300);
        }

        p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
        c.setParameters(p);
}
}

我需要单独的停顿。在 Flash 的每个 TURN_ON 或 TURN_OFF 之后或之前说。在每个循环中,它应该单独等待 Handler Run() 中的每一段代码。

4

2 回答 2

0

当我想“睡觉”时,我个人使用 Handler postDelayed

// "SLEEP" 2 SECONDS HERE ...
Handler handler = new Handler(); 
handler.postDelayed(new Runnable() { 
     public void run() { 
          p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); // Or watherver you want
          c.setParameters(p);
     } 
}, 2000); 

您还可以在线程中使用 sleep 方法来避免阻塞 UI 线程。

编辑: 这是编写递归处理程序的方法:这将允许您在另一个之后发送所有 Morse 部分

Handler handler = new Handler();
int i = 0;
Runnable myRunnable = new Runnable() {
        @Override
        public void run() {

            Log.d("handler is running", "true" + System.currentTimeMillis());
            if(i>5)
               handler.removeCallback(myRunnable);
            else{
                i++;
                handler.postDelayed(myRunnable, 100); // here is self calling
            }

        }
    };
}
handler.postDelayed(myRunnable, 100);
于 2013-08-12T11:10:05.427 回答
0

我使用 Thread 解决了这个问题。摩尔斯电码是通过单击按钮生成的。

    OnClickListener goMorse = new OnClickListener() {

    @Override
    public void onClick(View v) {

        new Thread () {
            public void run() {
                if(myMorseString != null){
                for (int x = 0; x < myMorseString.length(); x++) {
                    if (myMorseString.charAt(x) == '2') {
                        cam = Camera.open();
                        sleepTime = 500;
                        Parameters p = cam.getParameters();
                        p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                        cam.setParameters(p);
                        cam.startPreview();
                        try {
                            Thread.sleep(sleepTime);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        // power off after signal
                        cam.stopPreview();
                        cam.release();
                        cam = null;
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    if (myMorseString.charAt(x) == '1') {
                        cam = Camera.open();
                        sleepTime = 250;
                        Parameters p = cam.getParameters();
                        p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                        cam.setParameters(p);
                        cam.startPreview();
                        try {
                            Thread.sleep(sleepTime);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        // power off after signal
                        cam.stopPreview();
                        cam.release();
                        cam = null;
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    if (myMorseString.charAt(x) == '0') {
                        cam = Camera.open();
                        sleepTime = 250;
                        Parameters p = cam.getParameters();
                        cam.setParameters(p);
                        //cam.startPreview();
                        cam.stopPreview();
                        cam.release();
                        cam = null;

                        try {
                            Thread.sleep(sleepTime);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                }           
            }}}
        }.start();
    }

};
于 2014-04-14T20:14:07.147 回答