• 【四】注入框架RoboGuice使用:(Your First System Service Injection)


             上一篇我们简单的介绍了一下RoboGuice的使用(【三】注入框架RoboGuice使用:(Your First Resource Injection)),今天我们来看下系统服务的使用注解的方法:

         为了在Activity中系统服务使用注解,必须实现下面两个步骤:

            ①:创建继承RoboActivity的Activity

            ②:使用 @Inject来进行注解系统服务

          以下我们来实现一个样例,和上一篇文章样例差点儿相同,我们须要进行实现系统服务。我们相同创建一个继承RoboActivity的Activity,然后使用@Inject进行注解服务,其它的操作就放心交给Roboguice帮你做吧。

    class MyActivity extends RoboActivity {
        @Inject Vibrator vibrator;
        @Inject NotificationManager notificationManager;
    
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // we can use the instances directly!
            vibrator.vibrate(1000L); // RoboGuice took care of the getSystemService(VIBRATOR_SERVICE)
            notificationManager.cancelAll();
    
            // rest of your code
          从上面能够看出来。RoboGuice知道怎么样依据系统服务来获取该引用对象,假设你想知道RoboGuice内部是怎么样进行绑定服务的能够查看一下DefaultRoboModule.java,以下就是该源码

         

    package roboguice.config;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    
    import roboguice.activity.RoboActivity;
    import roboguice.event.EventManager;
    import roboguice.event.ObservesTypeListener;
    import roboguice.event.eventListener.factory.EventListenerThreadingDecorator;
    import roboguice.fragment.FragmentUtil;
    import roboguice.inject.AccountManagerProvider;
    import roboguice.inject.AssetManagerProvider;
    import roboguice.inject.ContentResolverProvider;
    import roboguice.inject.ContextScope;
    import roboguice.inject.ContextScopedSystemServiceProvider;
    import roboguice.inject.ContextSingleton;
    import roboguice.inject.ExtrasListener;
    import roboguice.inject.HandlerProvider;
    import roboguice.inject.InjectExtra;
    import roboguice.inject.InjectPreference;
    import roboguice.inject.InjectResource;
    import roboguice.inject.NullProvider;
    import roboguice.inject.PreferenceListener;
    import roboguice.inject.ResourceListener;
    import roboguice.inject.ResourcesProvider;
    import roboguice.inject.SharedPreferencesProvider;
    import roboguice.inject.SystemServiceProvider;
    import roboguice.inject.ViewListener;
    import roboguice.service.RoboService;
    import roboguice.util.Ln;
    import roboguice.util.LnImpl;
    import roboguice.util.LnInterface;
    
    import com.google.inject.Provider;
    import com.google.inject.Provides;
    import com.google.inject.Singleton;
    import com.google.inject.AbstractModule;
    import com.google.inject.matcher.Matchers;
    import com.google.inject.name.Named;
    import com.google.inject.name.Names;
    
    import android.app.Activity;
    import android.app.ActivityManager;
    import android.app.AlarmManager;
    import android.app.Application;
    import android.app.DownloadManager;
    import android.app.KeyguardManager;
    import android.app.NotificationManager;
    import android.app.SearchManager;
    import android.app.Service;
    import android.content.ContentResolver;
    import android.content.Context;
    import android.content.SharedPreferences;
    import android.content.pm.PackageInfo;
    import android.content.pm.PackageManager;
    import android.content.res.AssetManager;
    import android.content.res.Resources;
    import android.hardware.SensorManager;
    import android.location.LocationManager;
    import android.media.AudioManager;
    import android.net.ConnectivityManager;
    import android.net.wifi.WifiManager;
    import android.os.Build;
    import android.os.Build.VERSION;
    import android.os.Handler;
    import android.os.PowerManager;
    import android.os.Vibrator;
    import android.provider.Settings;
    import android.provider.Settings.Secure;
    import android.telephony.TelephonyManager;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.WindowManager;
    import android.view.inputmethod.InputMethodManager;
    
    /**
     * A Module that provides bindings and configuration to use Guice on Android.
     * Used by {@link roboguice.RoboGuice}.
     *
     * If you wish to add your own bindings, DO NOT subclass this class.  Instead, create a new
     * module that extends AbstractModule with your own bindings, then do something like the following:
     *
     * RoboGuice.setAppliationInjector( app, RoboGuice.DEFAULT_STAGE, Modules.override(RoboGuice.newDefaultRoboModule(app)).with(new MyModule() );
     *
     * @see com.google.inject.util.Modules#override(com.google.inject.Module...)
     * @see roboguice.RoboGuice#getOrCreateBaseApplicationInjector(android.app.Application, com.google.inject.Stage, com.google.inject.Module...)
     * @see roboguice.RoboGuice#newDefaultRoboModule(android.app.Application)
     * @see roboguice.RoboGuice#DEFAULT_STAGE
     *
     * @author Mike Burton
     */
    @SuppressWarnings("PMD")
    public class DefaultRoboModule extends AbstractModule {
        /**
         * Allows to retrieve the global, inter-context {@link EventManager}.  
         * you MUST get the global {@link EventManager} either via a field annotated with {@code @Inject @Named} 
         * or {@code getInjector.getInstance(key(EventManager.cass, Names.named())}.
         */
        public static final String GLOBAL_EVENT_MANAGER_NAME = "GlobalEventManager";
    
        @SuppressWarnings("rawtypes")
        private static Map<Class, String> mapSystemSericeClassToName = new HashMap<Class, String>();
    
        protected Application application;
        protected ContextScope contextScope;
        protected ResourceListener resourceListener;
        protected ViewListener viewListener;
    
        static {
            mapSystemSericeClassToName.put(LocationManager.class, Context.LOCATION_SERVICE);
            mapSystemSericeClassToName.put(WindowManager.class, Context.WINDOW_SERVICE);
            mapSystemSericeClassToName.put(ActivityManager.class, Context.ACTIVITY_SERVICE);
            mapSystemSericeClassToName.put(PowerManager.class, Context.POWER_SERVICE);
            mapSystemSericeClassToName.put(AlarmManager.class, Context.ALARM_SERVICE);
            mapSystemSericeClassToName.put(NotificationManager.class, Context.NOTIFICATION_SERVICE);
            mapSystemSericeClassToName.put(KeyguardManager.class, Context.KEYGUARD_SERVICE);
            mapSystemSericeClassToName.put(Vibrator.class, Context.VIBRATOR_SERVICE);
            mapSystemSericeClassToName.put(ConnectivityManager.class, Context.CONNECTIVITY_SERVICE);
            mapSystemSericeClassToName.put(WifiManager.class, Context.WIFI_SERVICE);
            mapSystemSericeClassToName.put(InputMethodManager.class, Context.INPUT_METHOD_SERVICE);
            mapSystemSericeClassToName.put(SensorManager.class, Context.SENSOR_SERVICE);
            mapSystemSericeClassToName.put(TelephonyManager.class, Context.TELEPHONY_SERVICE);
            mapSystemSericeClassToName.put(AudioManager.class, Context.AUDIO_SERVICE);
            if( VERSION.SDK_INT>=Build.VERSION_CODES.GINGERBREAD ) {
                mapSystemSericeClassToName.put(DownloadManager.class, Context.DOWNLOAD_SERVICE);
            }
        }
    
    
        public DefaultRoboModule(final Application application, ContextScope contextScope, ViewListener viewListener, ResourceListener resourceListener) {
            this.application = application;
            this.contextScope = contextScope;
            this.viewListener = viewListener;
            this.resourceListener = resourceListener;
        }
    
        /**
         * Configure this module to define Android related bindings.
         */
        @SuppressWarnings({ "rawtypes", "unchecked" })
        @Override
        protected void configure() {
    
            final Provider<Context> contextProvider = getProvider(Context.class);
            final EventListenerThreadingDecorator observerThreadingDecorator = new EventListenerThreadingDecorator();
    
            // Singletons
            bind(ViewListener.class).toInstance(viewListener);
    
            // ContextSingleton bindings
            bindScope(ContextSingleton.class, contextScope);
            //we need to super bind as we inject the scope by code only, not by annotations
            superbind(ContextScope.class).toInstance(contextScope);
            bind(AssetManager.class).toProvider(AssetManagerProvider.class);
            bind(Context.class).toProvider(NullProvider.<Context>instance()).in(ContextSingleton.class);
            bind(Activity.class).toProvider(NullProvider.<Activity>instance()).in(ContextSingleton.class);
            bind(RoboActivity.class).toProvider(NullProvider.<RoboActivity>instance()).in(ContextSingleton.class);
            bind(Service.class).toProvider(NullProvider.<Service>instance()).in(ContextSingleton.class);
            bind(RoboService.class).toProvider(NullProvider.<RoboService>instance()).in(ContextSingleton.class);
    
            // Sundry Android Classes
            bind(SharedPreferences.class).toProvider(SharedPreferencesProvider.class);
            bind(Resources.class).toProvider(ResourcesProvider.class);
            bind(ContentResolver.class).toProvider(ContentResolverProvider.class);
            bind(Application.class).toInstance(application);
            bind(EventListenerThreadingDecorator.class).toInstance(observerThreadingDecorator);
            bind(EventManager.class).annotatedWith(Names.named(GLOBAL_EVENT_MANAGER_NAME)).to(EventManager.class).asEagerSingleton();
            bind(Handler.class).toProvider(HandlerProvider.class);
    
            // System Services
            for( Entry<Class, String> entry : mapSystemSericeClassToName.entrySet() ) {
                bindSystemService(entry.getKey(), entry.getValue());
            }
    
            // System Services that must be scoped to current context
            bind(LayoutInflater.class).toProvider(new ContextScopedSystemServiceProvider<LayoutInflater>(contextProvider,Context.LAYOUT_INFLATER_SERVICE));
            bind(SearchManager.class).toProvider(new ContextScopedSystemServiceProvider<SearchManager>(contextProvider,Context.SEARCH_SERVICE));
    
            // Android Resources, Views and extras require special handling
            if( hasInjectionPointsForAnnotation(InjectResource.class) ) {
                bindListener(Matchers.any(), resourceListener);
            }
    
            if( hasInjectionPointsForAnnotation(InjectExtra.class) ) {
                final ExtrasListener extrasListener = new ExtrasListener(contextProvider);
                bindListener(Matchers.any(), extrasListener);
            }
    
            //should be bound only if we use InjectView or InjectFragment
            bindListener(Matchers.any(), viewListener);
    
            final PreferenceListener preferenceListener = new PreferenceListener(contextProvider,application);
            superbind(PreferenceListener.class).toInstance(preferenceListener);
            if( hasInjectionPointsForAnnotation(InjectPreference.class) ) {
                bindListener(Matchers.any(), preferenceListener);
            }
    
            //should always be bound as ContentViewListener relies on event system
            bindListener(Matchers.any(), new ObservesTypeListener(getProvider(EventManager.class), observerThreadingDecorator));
            requestInjection(observerThreadingDecorator);
    
            if( isInjectable(Ln.class)) {
                bind(LnInterface.class).to(LnImpl.class);
                //should this be placed in if statement ?
                requestStaticInjection(Ln.class);
            }
    
            bindDynamicBindings();
        }
    
        private <T> void bindSystemService(Class<T> c, String androidServiceName) {
            bind(c).toProvider(new SystemServiceProvider<T>(application, androidServiceName ));
        }
    
        @SuppressWarnings("unchecked")
        private void bindDynamicBindings() {
            // Compatibility library bindings
            if(FragmentUtil.hasSupport) {
                bind(FragmentUtil.supportFrag.fragmentManagerType()).toProvider(FragmentUtil.supportFrag.fragmentManagerProviderType());
            }
            if(FragmentUtil.hasNative) {
                bind(FragmentUtil.nativeFrag.fragmentManagerType()).toProvider(FragmentUtil.nativeFrag.fragmentManagerProviderType());
            }
    
            if( VERSION.SDK_INT>=Build.VERSION_CODES.ECLAIR ) {
                try {
                    @SuppressWarnings("rawtypes")
                    Class c = Class.forName("android.accounts.AccountManager");
                    bind(c).toProvider(AccountManagerProvider.class);
                } catch( Throwable ex ) {
                    Log.e(DefaultRoboModule.class.getName(), "Impossible to bind AccountManager", ex);
                }
            }
        }
    
        // ----------------------------------
        //  PROVIDER METHODS
        //  used for lazy bindings, when
        //  instance creation is costly.
        // ----------------------------------
    
        @Provides
        @Singleton
        public PackageInfo providesPackageInfo() {
            try {
                return application.getPackageManager().getPackageInfo(application.getPackageName(),0);
            } catch( PackageManager.NameNotFoundException e ) {
                throw new RuntimeException(e);
            }
        }
    
        @Provides
        @Named(Settings.Secure.ANDROID_ID)
        public String providesAndroidId() {
            String androidId = null;
            final ContentResolver contentResolver = application.getContentResolver();
            try {
                androidId = Secure.getString(contentResolver, Secure.ANDROID_ID);
            } catch( RuntimeException e) {
                // ignore Stub! errors for Secure.getString() when mocking in test cases since there's no way to mock static methods
                Log.e(DefaultRoboModule.class.getName(), "Impossible to get the android device Id. This may fail 'normally' when testing.", e);
            }
    
            if(!"".equals(androidId)) {
                return androidId;
            } else {
                throw new RuntimeException("No Android Id.");
            }
        }
    
    }

  • 相关阅读:
    java基础02标识符
    java基础08自增、自减运算符 初识Math
    java基础04 数据类型扩展及面试题讲解
    java基础03数据类型
    大家好,近期学习设计模式,我会把自己的例子上传,以供大家参考
    关于寂寞
    从以文件流的形式下载文件
    大家好,我的程序博客开始了
    如何学好C语言
    大学生如何将自己从迷茫中解困
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5193347.html
Copyright © 2020-2023  润新知