获取全局的Application对象

时间:2023-02-07 08:30:58

开发中很多地方需要使用全局Application对象,每次都从外部传入着实麻烦。于是,开始有有了利用Java的反射来获取,当前的Application对象。


package pk.base.util;

import android.app.Application;

import java.lang.reflect.Field;
import java.lang.reflect.Method;


/**  * @author zijiao  * @version 2015/12/29  * @Mark  */ public class ApplicationAccessor {

    private static final byte[] mLock = new byte[0];
    private static ApplicationAccessor mInstance;

    private static Application mApplication;

    private ApplicationAccessor() {
    }

    public static ApplicationAccessor instance() {
        if (mInstance == null) {
            synchronized (mLock) {
                if (mInstance == null) {
                    mInstance = new ApplicationAccessor();
                }
            }
        }
        return mInstance;
    }

    public Application get() {
        if (mApplication == null) {
            try {
                Class activityThreadClazz = Class.forName("android.app.ActivityThread");
                Method method = activityThreadClazz.getMethod("currentActivityThread");
                Object activityThreadObj = method.invoke(activityThreadClazz, new Object[0]);
                Class activityThreadCls = activityThreadObj.getClass();
                Field field = activityThreadCls.getDeclaredField("mInitialApplication");
                field.setAccessible(true);
                mApplication = (Application) field.get(activityThreadObj);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return mApplication;
    }

}
利用反射先取到ActivityThread中的currentActivityThread方法,以获取当前的ActivityThread实例,然后再通过反射得到mInitialApplication属性, 注意属性要进行暴力反射setAccessible(true)处理,否则无法获取field中对应的的值