5

NokiaS40でNullPointerExceptionが発生します。

この例外の原因を知りたいのですが。

デバイスは次のことを示しています。

NullPointerException java / lang / NullPointerException

このエラーはデバイスでのみ発生し、エミュレータで実行するとアプリケーションは正常に動作します。

micrologを使用してアプリケーションをデバッグします。ただし、ログが有効になっている場合、アプリケーションは正常に動作します。

このNullPointerExceptionを取得したときにスタックトレースを取得する方法はありますか?この例外の原因となる行番号など、すべての詳細は必要ありません。

更新:同じアプリケーションを別のNokia S40にインストールしましたが、同じエラーは発生しませんでした。

  • Nokia2660-エラー
  • Nokia6131-エラーなし

更新2:どういうわけか私はNullPointerExceptionの原因を見つけました。

    import javax.microedition.lcdui.Canvas;
    import javax.microedition.lcdui.Graphics;

    public class OuterClass extends Canvas {

    private Config config;

    public OuterClass() {
        this.config = new Config();
    }

    public void paint(Graphics graphics) {
        HelperClass helper = new HelperClass(this.config);
        helper.doStuff();
    }

    public void dispose() {
        this.config = null;
    }

    public class Config implements IConfig {
        public int getSomething() {
            // ...
        }
    }
}


 public class HelperClass {

        private IConfig config;

        public HelperClass(IConfig) {
            this.config = config;
        }

        public doStuff() {
            config.getSomething(); // Here is thrown NullPointerException
        }
    }

状況によっては、スレッドが開始され、helper.doStuff()がNPEを引き起こす前にOuterClass.dispose()を呼び出します。ログを有効にすると、スレッドが遅くなり、呼び出されると予想したときにhelper.doStuff()が呼び出されたと思います。

4

4 に答える 4

2

Nokia Series40 ハンドセットで Throwable スタック トレースを保存する方法を見つけることはできません。

Series40 で JavaME アプリケーションをデバッグする通常の強引な方法は、コードを変更してメモリ内にスタック トレースを自分で作成することです。

私が話しているのは:

  • 識別できる各スレッド (システム コールバック スレッドを含む) には、文字列を含む独自の Stack オブジェクトが必要です。明らかに、これによりアプリケーションのメモリ フットプリントがいくらか増加しますが、メモリ内に保持することで、競合状態への影響を制限できます。

  • コードがメソッドに入ると、メソッド シグネチャが現在のスレッド スタックに追加されます。メソッドが終了すると (メソッドごとに終了ポイントを 1 つだけにすることをお勧めします)、スタックの一番上にポップします。

  • コードのさまざまな場所にある変数の値など、スタックに追加のデバッグ情報を追加できます。

  • コード内のすべてのメソッドにこれを追加する必要はありません。

  • 特定したすべてのスレッドのエントリ ポイントに追加try{}catch(Throwable){}し、スタックをファイルまたは画面 (フォーム) にダンプできます。

明らかに、これは大規模な既存のコードベースの多くの場所に手動で追加したい種類の変更ではありません。ただし、将来のために組織のコーディング標準の一部にして、ソース コード解析スクリプトを記述して既存のコードに自動的に追加することができます。

于 2009-08-14T11:42:09.993 に答える
0

Microlog を使用して、例外が発生したときに電子メールを送信できます。

マイクロログ

于 2010-05-01T21:21:32.077 に答える
0

過去に、スタック トレースを標準出力以外の場所に出力しようとして、問題が発生しました。標準例外クラスは、出力ストリームを受け取る printStackTrace メソッドを提供しないため、標準出力ストリームにのみ出力されます。

少なくとも Java SE では、単に System.out = と言うだけで、Java 出力ストリームを別の場所にリダイレクトすることができます。PrintStream クラスは OutputStream を受け取ります。つまり、独自の ByteArrayOutputStream を作成し、PrintStream を初期化し、System.out をそのストリームに設定してから、ex.printStackTrace() を呼び出すことができます。私はここに J2ME 環境を持っていませんが、System.out を別のものに設定しようとして壊れない限り (ドキュメントでは読み取り専用であるとは何も言っていません)、できるはずです。それ。

それを行った後、それを専用の RecordStore に書き込み、その RecordStore のレコードをサーバーにアップロードして取得できるようにすることをお勧めします。

それほど簡単ではないことはわかっていますが、うまくいくかもしれません。最初に System.out をテストします。それが機能する場合、他のすべても機能するはずです。

私の答えは間違っていました。指摘したように、System.out および System.err フィールドは final と宣言されています。スタック トレースを取得できず、エミュレータでアプリケーションを実行してもエラーが発生しない場合は、コード (アラート、ログなど、可能なものすべて) にトレースの箇条書きを作成して、コードの一部を分離してみてください。問題が発生しています。エミュレーターと実際のデバイスの間で変更できるものでなければなりません。たとえば、RecordStore でのレコードの取得/保存、接続の開始などに関連するものです。問題が発生したときに何をしようとしましたか?

于 2009-08-14T04:31:13.430 に答える
-2

高レベルのtry/catchブロックで例外をキャッチしてから、トレースを自分宛てに電子メールで送信してみてください。

于 2009-08-13T19:59:45.110 に答える