1. ホーム
  2. アンドロイド

[解決済み】このHandlerクラスはstaticでなければリークが発生する可能性があります。IncomingHandler

2022-03-30 06:59:49

質問

Android 2.3.3のアプリケーションをサービス付きで開発しています。そのサービスの中で、Mainアクティビティと通信するために、このようなものを用意しています。

public class UDPListenerService extends Service
{
    private static final String TAG = "UDPListenerService";
    //private ThreadGroup myThreads = new ThreadGroup("UDPListenerServiceWorker");
    private UDPListenerThread myThread;
    /**
     * Handler to communicate from WorkerThread to service.
     */
    private Handler mServiceHandler;

    // Used to receive messages from the Activity
    final Messenger inMessenger = new Messenger(new IncomingHandler());
    // Use to send message to the Activity
    private Messenger outMessenger;

    class IncomingHandler extends Handler
    {
        @Override
        public void handleMessage(Message msg)
        {
        }
    }

    /**
     * Target we publish for clients to send messages to Incoming Handler.
     */
    final Messenger mMessenger = new Messenger(new IncomingHandler());
    [ ... ]
}

そして、ここにも。 final Messenger mMessenger = new Messenger(new IncomingHandler()); というLintの警告が表示されます。

This Handler class should be static or leaks might occur: IncomingHandler

どういう意味ですか?

どのように解決するのですか?

もし IncomingHandler クラスが静的でない場合、そのクラスはあなたの Service オブジェクトを作成します。

Handler オブジェクトはすべて共通のLooperオブジェクトを共有し、メッセージを投稿したり、読み込んだりします。

メッセージにはターゲット Handler メッセージキューにターゲットハンドラを持つメッセージがある限り、ハンドラはガベージコレクトされません。ハンドラが静的でない場合 Service または Activity は、破棄されてもガベージコレクションされることはありません。

これは、少なくともしばらくの間は、メッセージがキューに留まっている限り、メモリリークにつながる可能性があります。これは、長時間遅延するメッセージを投稿しない限り、さほど問題にはなりません。

を作成することができます。 IncomingHandler を静的にして WeakReference をサービスに追加します。

static class IncomingHandler extends Handler {
    private final WeakReference<UDPListenerService> mService; 

    IncomingHandler(UDPListenerService service) {
        mService = new WeakReference<UDPListenerService>(service);
    }
    @Override
    public void handleMessage(Message msg)
    {
         UDPListenerService service = mService.get();
         if (service != null) {
              service.handleMessage(msg);
         }
    }
}

こちらをご覧ください ポスト 参考文献:Romain Guy