web-dev-qa-db-ja.com

getActivity()。runOnUiThread(new Runnable(){でのNullPointerException

NPEにはさまざまな原因があることは知っていますが、私の場合は少し奇妙です(少なくとも私には)。

ActivitiesFragmentsに正常に変換しましたが、問題は日付を表示する関数に起因しているようです。アプリケーションが実行されているとき、すべてが正常に機能します。ただし、[戻る]ボタンを押すとすぐに。アプリの強制が終了すると、ログに102行目でNullPointerExceptionが表示されていることがわかります。そのため、コードを見て、これについて調査しましたが、残念ながら何も得られませんでした。

これは、戻るボタンを押したときにエラーが発生する行です。

getActivity().runOnUiThread(new Runnable(){

また、戻るボタンを無効にしようとしました(ランチャーを作成しているため、必要ありません)。しかし、機能していないようです。

以下は、メソッド/関数を表示する日付全体のコードです。

// (Calendar) Date function - Displays dateview on Card
final boolean keepRunning1 = true;
Thread thread_two = new Thread(){
    @Override
    public void run(){

        while(keepRunning1){

            // Make the thread wait half a second. If you want...
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                Toast.makeText(getActivity().getApplicationContext(), "Default Signature Fail", Toast.LENGTH_LONG).show();
                e.printStackTrace();
            }

                getActivity().runOnUiThread(new Runnable(){
                @Override
                public void run(){
                    TextView date = (TextView) getView().findViewById(R.id.date);
                    date.setText(DateUtils.formatDateTime(getActivity().getBaseContext(), System.currentTimeMillis(),DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR));
                }
            });
        }
    }
};

thread_two.start();

お時間をいただきありがとうございます。うまく行けば、私が間違っていることを明らかにすることができます。

Logcat-

05-23 21:17:33.216: E/AndroidRuntime(6906): Java.lang.NullPointerException: Attempt to invoke virtual method 'void Android.support.v4.app.FragmentActivity.runOnUiThread(Java.lang.Runnable)' on a null object reference
05-23 21:17:33.216: E/AndroidRuntime(6906):     at com.activelauncher.fragments.UtilsFragment$2.run(UtilsFragment.Java:102)
38
Robin

これは、スレッドが作業を終了したが、アクティビティが表示されなくなったときに発生することがほぼ確実です。

getActivity()呼び出しがnullを返すかどうかを確認する必要があります。

コードに修正を適用するには、次をご覧ください。

// (Calendar) Date function - Displays dateview on Card
final boolean keepRunning1 = true;
Thread thread_two = new Thread(){

@Override
public void run(){

    while(keepRunning1){

        // Make the thread wait half a second. If you want...
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            Toast.makeText(getActivity().getApplicationContext(), "Default Signature                         Fail", Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }

        // here you check the value of getActivity() and break up if needed
        if(getActivity() == null)
            return;

        getActivity().runOnUiThread(new Runnable(){
        @Override
        public void run(){
           TextView date = (TextView) getView().findViewById(R.id.date);
           date.setText(DateUtils.formatDateTime(getActivity().getBaseContext(), System.currentTimeMillis(),DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR));
           }
         });
    }
}
};thread_two.start();
59
Farouk Touzi

バックを押した後、バックグラウンドスレッドはまだ実行中です。スレッドがgetActivity().runOnUiThread()コードに到達するまでに、アクティビティは存在しなくなります。アクティビティが次のようにまだ存在するかどうかを確認します。

if (getActivity() != null) {
        getActivity().runOnUiThread(new Runnable(){
                @Override
                public void run(){
                    TextView date = (TextView) getView().findViewById(R.id.date);
                    date.setText(DateUtils.formatDateTime(getActivity().getBaseContext(), System.currentTimeMillis(),DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR));
            }
        });
}
17
Mark Pazon

プット

_if(getActivity() == null)
        return;
_

getActivity().runOnUiThread(new Runnable(){の前に[戻る]ボタンが閉じられ、Threadがまだ実行されている場合、呼び出しActivityがまだ存在するかどうかを確認します。

そうでない場合は、returnになります。

9
Apoorv

NPEの理由は、スレッドがフラグメントライフサイクルにバインドされていないためです。フラグメントがホスティングアクティビティから切り離されると、getActivity()はnullを返します。

解決策として、スレッドを完全に削除し、UIスレッドのHandlerpostDelayed()を使用して、遅延後に必要な更新を行うRunnablesを投稿することを検討してください。

8
laalto

これを試して

TextView date = (TextView) getView().findViewById(R.id.date);

日付がnullであるか、チェックされていない

if(date !=null){
                    date.setText(DateUtils.formatDateTime(getActivity().getBaseContext(), System.currentTimeMillis(),DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR));
}
5
Macrosoft-Dev