5

以下のコードで、Eclipse は「この Handler クラスは静的である必要があります。そうしないと、リークが発生する可能性があります」という警告を生成します。

public class MyActivity extends Activity implements Runnable
 {
   final Handler handler = new Handler()
    {
      @Override
      public void handleMessage( Message message)
       {
         String sResult = (String) message.obj;
         if( (sResult != null) && (sResult != ""))
           {
             MyNonStatic = (TableLayout) findViewById( R.id.tableLayout); // any non-static method
           }
         return;
       }
    };


   public void run()
    {
      final Message message = handler.obtainMessage( 1, MyFunction( context));
      handler.sendMessage( message);
    }

   public String MyFunction( Context context)
    {
      return "MyNewString";
    }
  }

サイトで多くのトピックを確認していますが、解決策がありません。このコードを教えてください。

追加: handleMessage() で非静的メソッド (findViewById() など) を呼び出す必要があります!

4

3 に答える 3

2

ハンドラー-コールバックが発生するスレッドを識別するハンドラー。nullの場合、コールバックはプロセスのスレッドプールから発生します。

状況を想像してみてください。一部のアクティビティは、を呼び出しPendingIntent.send(...)て配置しnon-static inner subclass of Handlerます。そして、活動は破壊されます。しかし、インナークラスは生きています

内部クラスは、破棄されたアクティビティへのリンクを保持しているため、ガベージコレクションを行うことはできません。

したがって、静的にする必要があります。

出典:Androidのハンドラーとメモリリーク

于 2012-11-22T06:57:00.747 に答える
2

Android lint チェックから:

ハンドラーリーク
-----------
概要: Handler クラスが への参照を保持しないようにします。
外側のクラス

優先度: 4 / 10
重大度: 警告
カテゴリ: パフォーマンス

Android では、Handler クラスを静的にする必要があります。そうしないと、リークが発生する可能性があります。メッセージ
アプリケーション スレッドの MessageQueue にエンキューされたものも、そのターゲットを保持します
ハンドラ。ハンドラーが内部クラスの場合、その外部クラスはそのまま保持されます。
良い。外部クラスのリークを避けるために、Handler を static ネストされたものとして宣言します。
外部クラスへの WeakReference を持つクラス。

警告の最初の部分はfinal Handler handler = new Handler()、匿名の内部クラスを作成するためです。内部クラスはスタンドアロンの方法で作成することはできません。常に外部インスタンスが必要です。これを Java で作成する方法を思い出してくださいOuterClass.InnerClass innerObject = outerObject.new InnerClass();Outer.thisすべての内部クラス オブジェクトは、外部のメンバーにアクセスするために、外部オブジェクトへの参照も保持する必要があります。

2 番目の部分にはfinal Message message = handler.obtainMessage( 1, MyFunction( context));、内側のハンドラー クラスへのハンドルがあります (これには、外側のアクティビティ クラスへのハンドラーがあります)。このメッセージが長く続くと、Activity をガベージ コレクションできなくなります。

メッセージの処理を妨げるものは何ですか? 残念ながら、lint ツールはそれを把握できないため、メモリ リークの可能性について常に警告します。自分が何をしているのか確信がある場合は、さまざまな方法でこれらのメッセージを抑制することができます。

Activityあなたの場合、を作成するのは良い考えではないように見えますRunnableが、とにかくHandler.postまたは最高のActivity.runOnUIThreadを使用する必要があります。

于 2012-11-22T08:11:01.747 に答える