1

ということでトーチアプリを作ってみたのですが・・・ 通常のトーチ機能は問題なく動作しています。

次に、ANR を引き起こす可能性のある以下の機能について説明します。たとえば、点滅フラッシュを介して SOS メッセージ (モールス信号) を送信したいとします。(その 111-000-111) つまり、オン-オン-オン-オフ-オフ-オフ-と繰り返します。

(ゆっくり読んでください)少しの間「オン」にしてから、少し点滅させて、もう一度「オン」にします - これは、2 つの連続した「オン」を区別するためです。

問題は、Time delay のために、スレッドをスリープ状態にすることです (この方法は私にとって最も効果的でした)。

ここに私のサンプル関数があります.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 ミリ秒の待機期間は多少重複しています。この期間が終了すると、すべてのコードが同時に実行されるため、まったく意味がありません。

これを試してみたところ、Flash はかなり速く点滅し、希望する微妙な一時停止や点滅効果はありませんでした。

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

UI スレッドのブロックを回避するために、スレッドで sleep メソッドを使用することもできます。

編集: これは、再帰ハンドラーを作成する方法です:これにより、すべてのモールス部分を他の部分の後に送信できます

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 に答える