0

バックグラウンド スレッドを実行する気象データを表示するフラグメントがあります。このスレッドは、基本的にメイン UI で関数を呼び出して、予報がまだ有効かどうかを確認するだけです。この関数は UI を更新するので、次のように を使用してメイン スレッドにHandler投稿しています。Runnable

public class WaveFxListFragment extends Fragment implements
        LoaderManager.LoaderCallbacks<Cursor>, View.OnClickListener {

    // .....

    // handler for dealing with synchronising update thread with UI
    private Handler mHandler;
    private UpdateThread mUpdateThread;

    private class UpdateThread extends Thread {
        volatile boolean running = false;

        @Override
        public void run() {
            running = true;

            while (running) {
                // get main UI thread to perform update check:
                Log.d(TAG, "Handler is " + mHandler);
                mHandler.post(new Runnable() { // getting null pointer error here!
                    @Override
                    public void run() {
                        checkValidTime();
                    }
                });

                try {
                    Thread.sleep(1000); // sleep 1 second
                } catch (InterruptedException e) {
                    Log.d(TAG, "Thread was interrupted!");
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Reuse existing handler:
        mHandler = getActivity().getWindow().getDecorView().getHandler();
    }

    @Override
    public void onResume() {
        super.onResume();
        // start update checker:
        mUpdateThread = new UpdateThread();
        mUpdateThread.start();
    }

    @Override
    public void onPause() { 
            // stop update thread
            Log.d(TAG, "Asking thread to stop");
            mUpdateThread.running = false;

            super.onPause();
    }
}

これは正常に機能します。問題は、画面の向きを変更したときです。Runnable現在のアクティビティは破棄され、スレッドが実行中の場合は、存在しなくなった UI スレッドに投稿しようとします。そのため、クラスrunningにメンバー変数を配置し、アクティビティが呼び出されたときにif を設定します。ただし、 変数を false に設定しても、スレッドは引き続き a を投稿しようとしますが、現在は null です! そこまで行くべきではありませんが、そうです!UpdateThreadfalseonPauseUpdateThread.runningRunnableHandler

私はこれを間違っていますか?私のログメッセージ「スレッドに停止を求めています」が出力されるので、running を false に設定するところまで到達していることがわかります。

誰でも洞察を提供できますか?

ありがとう

4

1 に答える 1

0

これを解決するためにできることがいくつかあります。

  1. running を false に設定した後、スレッドを中断します。これにより、スレッドが早期に終了するか、少なくともエラーが早期に表示されるようになります。

  2. 更新スレッドでハンドラーが null でないことを確認し、onPause で null に設定します。

  3. mHandler の割り当てを onResume に移動して、更新スレッドが呼び出されたときに mHandler が有効であることを確認します。

于 2013-04-29T22:38:03.113 に答える