Android处理程序在屏幕方向更改时丢失

时间:2015-01-11 18:54:07

标签: java android

我创建了一个简单的间隔运行计时器,它可以工作。 唯一的问题是当屏幕方向改变时(运行时可能会发生)UI线程的处理程序丢失(我认为),并且在运行结束时UI不会更新。

你们可以帮助我吗?

这是我的代码:

public class MainActivity extends Activity {

    private Thread workerThread;
    private Handler uiHandler;

    private EditText input;
    private Button start, stop;
    private ImageView image;

    @Override protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Getting references to views
        input = (EditText) findViewById(R.id.input);
        start = (Button) findViewById(R.id.start);
        stop = (Button) findViewById(R.id.stop);
        image = (ImageView) findViewById(R.id.flash);

        //Other vars
        uiHandler = new Handler();
        final String tag = "MainActivity";
        final Pattern regex = Pattern.compile("^" +
                                                      "\\d+ (" +
                                                      "  (\\.\\d+) |" +
                                                      "  (\\(" +
                                                      "   \\d+((\\.\\d+)?  (,\\d+((\\.\\d+)?))*" +
                                                      "  \\))" +
                                                      "))?" +

                                                      "(,\\d+ (" +
                                                      "  (\\.\\d+) |" +
                                                      "  (\\(" +
                                                      "   \\d+((\\.\\d+)?  (,\\d+((\\.\\d+)?))*" +
                                                      "  \\))" +
                                                      "))?)*" +
                                                      "$"
                                                     , Pattern.COMMENTS);

        //Restore previous state
        try {
            setUIRunning(savedInstanceState.getBoolean("running"));
        } catch (Exception e) {
            //New instance, do nothing
        }

        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick (View v) {

                final List<Double> schedule;

                //Process the input
                try {
                    schedule = processInput(regex, input.getText().toString());

                //Bad input, show a toast and stop
                } catch (RegexFailedException e) {
                    Toast.makeText(getApplicationContext(), e.msg, Toast.LENGTH_SHORT).show();
                    return;
                }

                Log.v(tag, "Current running list: " + schedule.toString());

                workerThread = new Thread(new Runnable() {
                    @Override
                    public void run () {

                        //SetUiRunning, but as a Runnable
                        class setUiRunningRunnable implements Runnable {

                            boolean par;

                            setUiRunningRunnable (boolean par) {
                                this.par = par;
                                uiHandler.post(this);
                            }

                            @Override public void run () { setUIRunning(par); }

                        }

                        class Flash {

                            public void run () {

                                uiHandler.post(new Runnable() {
                                    @Override
                                    public void run () {
                                        //Show red
                                        image.setVisibility(View.VISIBLE);
                                        //Beep
                                        (new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100))
                                                .startTone(ToneGenerator.TONE_CDMA_ABBR_ALERT, 500);
                                    }
                                });

                                try {
                                    Thread.sleep(500);
                                } catch (InterruptedException e) {
                                    Log.d(tag, "Sleeping (in flash) interrupted");
                                    return;
                                }

                                //Hide red
                                uiHandler.post(new Runnable() {
                                    @Override
                                    public void run () {
                                        image.setVisibility(View.GONE);
                                    }
                                });
                            }
                        }
                        final Flash flash = new Flash();

                        class Main {
                            public void run () {

                                for (double interval : schedule) {

                                    Long sleep = Math.round(interval * 60 * 1000);

                                    try {
                                        Log.d(tag, "sleeping for " + sleep + " ms");
                                        Thread.sleep(sleep);
                                    } catch (InterruptedException e) {
                                        Log.d(tag, "Sleeping interrupted");
                                        return;
                                    }

                                    flash.run();
                                    Log.d(tag, "run flash");
                                }

                            }
                        }
                        final Main main = new Main();

                        //Thread started, updating the UI to running
                        new setUiRunningRunnable(true);
                        Log.d(tag, "thread started");

                        main.run();

                        //Thread started, updating the UI to idle
                        new setUiRunningRunnable(false);
                        Log.d(tag, "thread stopped");

                    }
                });
                workerThread.start();

            }
        });

        stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick (View v) {
                setUIRunning(false);
                workerThread.interrupt();
            }
        });

    }

任何一般性建议也值得赞赏:)

1 个答案:

答案 0 :(得分:0)

当方向更改时,系统会重新创建活动,因此请尝试将此行添加到

避免在 AndroidMainfest.xml

中重新创建
android:configChanges="orientation|screenSize|keyboardHidden"

它可能会解决您的问题。