107b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko/* 207b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * Copyright (C) 2015 The Android Open Source Project 307b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * 407b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * Licensed under the Apache License, Version 2.0 (the "License"); 507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * you may not use this file except in compliance with the License. 607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * You may obtain a copy of the License at 707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * 807b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * http://www.apache.org/licenses/LICENSE-2.0 907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * 1007b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * Unless required by applicable law or agreed to in writing, software 1107b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * distributed under the License is distributed on an "AS IS" BASIS, 1207b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1307b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * See the License for the specific language governing permissions and 1407b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * limitations under the License 1507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko */ 1607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko 1707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalkopackage com.android.tv.common; 1807b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko 1907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalkoimport android.os.Handler; 2007b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalkoimport android.os.Looper; 2107b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalkoimport android.os.Message; 2207b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalkoimport android.support.annotation.NonNull; 2307b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko 2407b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalkoimport java.lang.ref.WeakReference; 2507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko 2607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko/** 2707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * A Handler that keeps a {@link WeakReference} to an object. 2807b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * 2907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * <p>Use this to prevent leaking an Activity or other Context while messages are still pending. 3007b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * When you extend this class you <strong>MUST NOT</strong> use a non static inner class, or the 3107b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * containing object will still be leaked. 3207b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * 3307b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * <p>See <a href="http://android-developers.blogspot.com/2009/01/avoiding-memory-leaks.html"> 3407b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * Avoiding memory leaks</a>. 3507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko */ 3607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalkopublic abstract class WeakHandler<T> extends Handler { 3707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko private final WeakReference<T> mRef; 3807b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko 3907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko /** 4007b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * Constructs a new handler with a weak reference to the given referent using the provided 4107b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * Looper instead of the default one. 4207b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * 4307b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * @param looper The looper, must not be null. 4407b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * @param ref the referent to track 4507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko */ 4607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko public WeakHandler(@NonNull Looper looper, T ref) { 4707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko super(looper); 4807b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko mRef = new WeakReference<>(ref); 4907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko } 5007b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko 5107b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko /** 5207b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * Constructs a new handler with a weak reference to the given referent. 5307b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * 5407b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * @param ref the referent to track 5507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko */ 5607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko public WeakHandler(T ref) { 5707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko mRef = new WeakReference<>(ref); 5807b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko } 5907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko 6007b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko /** 6107b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * Calls {@link #handleMessage(Message, Object)} if the WeakReference is not cleared. 6207b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko */ 6307b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko @Override 6407b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko public final void handleMessage(Message msg) { 6507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko T referent = mRef.get(); 6607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko if (referent == null) { 6707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko return; 6807b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko } 6907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko handleMessage(msg, referent); 7007b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko } 7107b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko 7207b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko /** 7307b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * Subclasses must implement this to receive messages. 7407b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * 7507b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * <p>If the WeakReference is cleared this method will no longer be called. 7607b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * 7707b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * @param msg the message to handle 7807b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko * @param referent the referent. Guaranteed to be non null. 7907b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko */ 8007b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko protected abstract void handleMessage(Message msg, @NonNull T referent); 8107b043dc3db83d6d20f0e8513b946830ab00e37bNick Chalko} 82