package com.koushikdutta.ion; import android.annotation.TargetApi; import android.app.Activity; import android.app.ActivityManager; import android.app.Fragment; import android.app.Service; import android.content.Context; import android.os.Build; import android.widget.ImageView; import java.lang.ref.WeakReference; import java.util.List; /** * Created by koush on 4/15/14. */ abstract class ContextReference<T> extends WeakReference<T> { ContextReference(T t) { super(t); } abstract static class NormalContextReference<T extends Context> extends ContextReference<T> { NormalContextReference(T context) { super(context); } static String isAlive(Context context) { if (context instanceof Service) return ServiceContextReference.isAlive((Service) context); if (context instanceof Activity) return ActivityContextReference.isAlive((Activity) context); return null; } @Override public Context getContext() { return get(); } } static class ServiceContextReference extends NormalContextReference<Service> { public ServiceContextReference(Service service) { super(service); } static String isAlive(Service candidate) { if (candidate == null) return "Service reference null"; ActivityManager manager = (ActivityManager)candidate.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningServiceInfo> services = manager.getRunningServices(Integer.MAX_VALUE); if (services == null) return "Could not retrieve services from service manager"; for (ActivityManager.RunningServiceInfo service: services) { if (candidate.getClass().getName().equals(service.service.getClassName())) { return null; } } return "Service stopped"; } @Override public String isAlive() { return isAlive(get()); } } static class ActivityContextReference extends NormalContextReference<Activity> { public ActivityContextReference(Activity activity) { super(activity); } static String isAlive(Activity a) { if (a == null) return "Activity reference null"; if (a.isFinishing()) return "Activity finished"; return null; } @Override public String isAlive() { return isAlive(get()); } } @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) static class FragmentContextReference extends ContextReference<Fragment> { public FragmentContextReference(Fragment fragment) { super(fragment); } @Override public Context getContext() { Fragment fragment = get(); if (fragment == null) return null; return fragment.getActivity(); } @Override public String isAlive() { Fragment fragment = get(); if (fragment == null) return "Fragment reference null"; String ret = ActivityContextReference.isAlive(fragment.getActivity()); if (ret != null) return ret; if (fragment.isDetached()) return "Fragment detached"; return null; } } static class SupportFragmentContextReference extends ContextReference<android.support.v4.app.Fragment> { public SupportFragmentContextReference(android.support.v4.app.Fragment fragment) { super(fragment); } @Override public Context getContext() { android.support.v4.app.Fragment fragment = get(); if (fragment == null) return null; return fragment.getActivity(); } @Override public String isAlive() { android.support.v4.app.Fragment fragment = get(); if (fragment == null) return "Fragment reference null"; String ret = ActivityContextReference.isAlive(fragment.getActivity()); if (ret != null) return ret; if (fragment.isDetached()) return "Fragment detached"; return null; } } static class ImageViewContextReference extends ContextReference<ImageView> { public ImageViewContextReference(ImageView imageView) { super(imageView); } @Override public String isAlive() { ImageView iv = get(); if (iv == null) return "ImageView reference null"; return NormalContextReference.isAlive(iv.getContext()); } @Override public Context getContext() { ImageView iv = get(); if (iv == null) return null; return iv.getContext(); } } public static ContextReference fromContext(Context context) { if (context instanceof Service) return new ServiceContextReference((Service)context); if (context instanceof Activity) return new ActivityContextReference((Activity)context); return new NormalContextReference<Context>(context) { @Override public String isAlive() { Context context = get(); if (context == null) return "Context reference null"; return null; } }; } public abstract String isAlive(); public abstract Context getContext(); }