2.基于Dagger2.38.1版本源码理解hilt注解-@AndroidEntryPoint或@HiltAndroidApp

前言

@AndroidEntryPoint用于修饰ComponentActivity、Service、Broadcast、service、Fragment、View。@HiltAndroidApp用于修饰Application;

注解规则

  1. 节点使用@HiltAndroidApp或@AndroidEntryPoint注解修饰有且仅有一个;

  2. @HiltAndroidApp或@AndroidEntryPoint注解只能用于修饰类,而不能用于修饰接口;

  3. @HiltAndroidApp或@AndroidEntryPoint注解修饰的类不能使用泛型;

  4. @HiltAndroidApp或@AndroidEntryPoint注解value值默认使用Void.class,我们最好不要去改动;

  5. 一个项目中@HiltAndroidApp只允许出现一次;

  6. baseElement表示@HiltAndroidApp或@AndroidEntryPoint注解修饰的类的父类,如果baseElement使用了@AndroidEntryPoint注解修饰:

  • (1) @AndroidEntryPoint注解修饰的类 和 其baseElement节点要么都使用@WithFragmentBindings注解修饰,要么都不要使用该注解;

  • (2) @AndroidEntryPoint注解修饰的类不要使用@OptionalInject修饰的注解修饰 || baseElement类型使用@OptionalInject修饰的注解修饰;

  1. @HiltAndroidApp只能用于修饰Application的继承类;

  2. @AndroidEntryPoint可用于修饰Activity、Service、Broadcast_service,Fragment,View:

  • (1)@AndroidEntryPoint用于修饰Activity时,只能修饰androidx.activity.ComponentActivity的继承节点;

  • (2)@AndroidEntryPoint不能用于修饰Application的继承类。

代码生成工作

@HiltAndroidApp或@AndroidEntryPoint修饰的节点生成xx_GeneratedInjector类

只要使用@HiltAndroidApp或@AndroidEntryPoint修饰的节点都会生成xx_GeneratedInjector类。

demo:

@AndroidEntryPoint
class UserListFragment : Fragment() {...}

生成的类:

	@OriginatingElement(
	    topLevelClass = UserListFragment.class
	)
	@GeneratedEntryPoint
	@InstallIn(FragmentComponent.class)
	public interface UserListFragment_GeneratedInjector {
	  void injectUserListFragment(UserListFragment userListFragment);
	}

@HiltAndroidApp修饰的Application实现类生成类

生成Hilt_xx类。这个类的作用是实现依赖注入到@HiltAndroidApp修饰的Application类中。

demo:

@HiltAndroidApp
class MyApplication : Application() {...}

生成Hilt_MyApplication类:

//A generated base class to be extended by the @HiltAndroidApp annotated class. If using the Gradle plugin, this is swapped as the base class via bytecode transformation.
 @Generated("ApplicationGenerator")
 abstract class Hilt_MyApplication extends Application implements GeneratedComponentManagerHolder {

        private final ApplicationComponentManager componentManager =
         new ApplicationComponentManager(
          new ComponentSupplier() {
              @Override
              public Object get() {
			   //_com_aregyan_github_Application_HiltComponents内部类SingletonComponent生成的,该类后面生成。
               return Dagger_com_aregyan_github_MyApplication_HiltComponents_SingletonComponent.builder()
                   .applicationContextModule(new ApplicationContextModule(Hilt_MyApplication.this))
                  .build();
               }
           }
         );

	@Override
     public final ApplicationComponentManager componentManager() {
       return componentManager;
     }

	@Override
     public final Object generatedComponent() {
       return this.componentManager().generatedComponent();
     }

 	 @CallSuper
     @Override
     public void onCreate() {
       // This is a known unsafe cast, but is safe in the only correct use case:
       // $APP extends Hilt_$APP
       ((MyApplication_GeneratedInjector)generatedComponent()).injectMyApplication((MyApplication) this);
       super.onCreate();
     }
 }

ApplicationComponentManager类是使用单例创建自己,该类的目的是创建SingtonComponent实现类。

  • ApplicationComponentManager和GeneratedComponentManagerHolder的作用已经描述,这里代码就不粘贴了,有兴趣可以自行去查看。

在Hilt_MyApplication实现了注入工作,那么一定有一个component容器:

  @Component
  @Singleton
  public static abstract class SingletonComponent 
  	implements Application_GeneratedInjector
  		
  {
  	
  	//Application_GeneratedInjector类中的方法
  	//void injectApplication(Application application);

	//实际是ActivityRetainedComponent,方便讲解我们暂用ActivityRetainedComponent
  	ActivityComponent.Builder componentBuilder();
 

  	@Component.Builder
  	public static interface Builder{
  		Builder applicationContextModule(ApplicationContextModule context);
 
  		SingletonComponent build();
  	}
  }

@AndroidEntryPoint修饰的ComponentActivity生成类

生成Hilt_xx类。这个类有两个目的:

  1. 将依赖注入到 @AndroidEntryPoint修饰的ComponentActivity类中;

  2. 提供ViewModelProvider.Factory,将我们自定义的ViewModel类实例化并且提供给ViewModel的工厂。(暂时不进行讲解,后面会说到)

demo:

@AndroidEntryPoint
class MainActivity : AppCompatActivity(R.layout.activity_main)

MainActivity生成Hilt_MainActivity类:

/**
 * A generated base class to be extended by the @dagger.hilt.android.AndroidEntryPoint annotated class. If using the Gradle plugin, this is swapped as the base class via bytecode transformation.
 */
public abstract class Hilt_MainActivity extends AppCompatActivity implements GeneratedComponentManagerHolder {
  private volatile ActivityComponentManager componentManager;

  private final Object componentManagerLock = new Object();

  private boolean injected = false;

  Hilt_MainActivity() {
    super();
    _initHiltInternal();
  }

  Hilt_MainActivity(int contentLayoutId) {
    super(contentLayoutId);
    _initHiltInternal();
  }

  private void _initHiltInternal() {
    addOnContextAvailableListener(new OnContextAvailableListener() {
      @Override
      public void onContextAvailable(Context context) {
        inject();
      }
    });
  }

  @Override
  public final Object generatedComponent() {
    return this.componentManager().generatedComponent();
  }

  protected ActivityComponentManager createComponentManager() {
    return new ActivityComponentManager(this);
  }

  @Override
  public final ActivityComponentManager componentManager() {
    if (componentManager == null) {
      synchronized (componentManagerLock) {
        if (componentManager == null) {
          componentManager = createComponentManager();
        }
      }
    }
    return componentManager;
  }

  protected void inject() {
    if (!injected) {
      injected = true;
      ((MainActivity_GeneratedInjector) this.generatedComponent()).injectMainActivity(UnsafeCasts.unsafeCast(this));
    }
  }

  @Override
  public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
    return DefaultViewModelFactories.getActivityFactory(this, super.getDefaultViewModelProviderFactory());
  }
}

如上代码所示,inject()实现依赖注入工作,getDefaultViewModelProviderFactory方法提供hilt源码中自定义的ViewModelProvider.Factory类。@AndroidEntryPoint修饰的ComponentActivity类使用ActivityComponent容器:

  @subComponent
  @ActivityScoped
  public static abstract class ActivityComponent 
  	implements
  		MainActivity_GeneratedInjector
  {
  	//MainActivity_GeneratedInjector中的方法		
  	//void injectMainActivity(MainActivity mainActivity);
  	
  	ViewModelComponent.Builder getViewModelComponentBuilder();
  	
  	FragmentComponent.Builder fragmentComponentBuilder();
  	
  	@SubComponent.Builder
  	static interface Builder{
  		
  		Builder activity(
  				@BindsInstance
  						Activity activity);
 
  		ActivityComponent build();
  	}
  }

@AndroidEntryPoint修饰的BroadcastReceiver生成类

@AndroidEntryPoint修饰的BroadcastReceiver实现类生成代码。

生成的代码如下:

@Generated("BroadcastReceiverGenerator")
abstract class Hilt_$CLASS extends $BASE {

	private volatile boolean injected = false;
	private final Object injectedLock = new Object();

	protected void inject(Context context) {
       if (!injected) {
			synchronized (injectedLock){
				if (!injected){
					(($CLASS_GeneratedInjector)BroadcastReceiverComponentManager.generatedComponent(context)).inject$CLASS(($CLASS) this);
				}
			}
         
         injected = true;
       }
     }

     @CallSuper
     @Override
     public void onReceive(Context context, Intent intent) {
       inject(context);
       super.onReceive(context, intent);
     }

}

AndroidEntryPoint修饰的Fragment生成类

生成Hilt_xx类。这个类有两个目的:

  1. 将依赖注入到 @AndroidEntryPoint修饰的Fragment类中;

  2. 提供ViewModelProvider.Factory,将我们自定义的ViewModel类实例化并且提供给ViewModel的工厂。(暂时不进行讲解,后面会说到)

demo:

@AndroidEntryPoint
class UserListFragment : Fragment() {...}

生成Hilt_xx类:

/**
 * A generated base class to be extended by the @dagger.hilt.android.AndroidEntryPoint annotated class. If using the Gradle plugin, this is swapped as the base class via bytecode transformation.
 */
public abstract class Hilt_UserListFragment extends Fragment implements GeneratedComponentManagerHolder {
  private ContextWrapper componentContext;

  private boolean disableGetContextFix;

  private volatile FragmentComponentManager componentManager;

  private final Object componentManagerLock = new Object();

  private boolean injected = false;

  Hilt_UserListFragment() {
    super();
  }

  Hilt_UserListFragment(int contentLayoutId) {
    super(contentLayoutId);
  }

  @Override
  @CallSuper
  public void onAttach(Context context) {
    super.onAttach(context);
    initializeComponentContext();
    inject();
  }

  @Override
  @SuppressWarnings("deprecation")
  @CallSuper
  @MainThread
  public void onAttach(Activity activity) {
    super.onAttach(activity);
    Preconditions.checkState(componentContext == null || FragmentComponentManager.findActivity(componentContext) == activity, "onAttach called multiple times with different Context! Hilt Fragments should not be retained.");
    initializeComponentContext();
    inject();
  }

  private void initializeComponentContext() {
    if (componentContext == null) {
      // Note: The LayoutInflater provided by this componentContext may be different from super Fragment's because we getting it from base context instead of cloning from the super Fragment's LayoutInflater.
      componentContext = FragmentComponentManager.createContextWrapper(super.getContext(), this);
      disableGetContextFix = FragmentGetContextFix.isFragmentGetContextFixDisabled(super.getContext());
    }
  }

  @Override
  public Context getContext() {
    if (super.getContext() == null && !disableGetContextFix) {
      return null;
    }
    initializeComponentContext();
    return componentContext;
  }

  @Override
  public LayoutInflater onGetLayoutInflater(Bundle savedInstanceState) {
    LayoutInflater inflater = super.onGetLayoutInflater(savedInstanceState);
    return LayoutInflater.from(FragmentComponentManager.createContextWrapper(inflater, this));
  }

  @Override
  public final Object generatedComponent() {
    return this.componentManager().generatedComponent();
  }

  protected FragmentComponentManager createComponentManager() {
    return new FragmentComponentManager(this);
  }

  @Override
  public final FragmentComponentManager componentManager() {
    if (componentManager == null) {
      synchronized (componentManagerLock) {
        if (componentManager == null) {
          componentManager = createComponentManager();
        }
      }
    }
    return componentManager;
  }

  protected void inject() {
    if (!injected) {
      injected = true;
      ((UserListFragment_GeneratedInjector) this.generatedComponent()).injectUserListFragment(UnsafeCasts.unsafeCast(this));
    }
  }

  @Override
  public ViewModelProvider.Factory getDefaultViewModelProviderFactory() {
    return DefaultViewModelFactories.getFragmentFactory(this, super.getDefaultViewModelProviderFactory());
  }
}

AndroidEntryPoint修饰的Service生成类

AndroidEntryPoint修饰的Service实现类生成代码如下:

//A generated base class to be extended by the @AndroidEntryPoint annotated class. If using the Gradle plugin, this is swapped as the base class via bytecode transformation.
@Generated("ServiceGenerator")
abstract class Hilt_$CLASS extends $BASE {

	private boolean injected = false;

 	protected void inject() {
       if (!injected) {
         generatedComponent().inject$CLASS(($CLASS) this);
         injected = true;
       }
     }

	private final Object componentManagerLock = new Object();

	private volatile ServiceComponentManager componentManager;

	protected ServiceComponentManager createComponentManager() {
       return new ServiceComponentManager(this);
     }

	@Override
     public ServiceComponentManager componentManager() {
       if (componentManager == null) {
         synchronize (componentManagerLock) {
           if (componentManager == null) {
             componentManager = createComponentManager();
           }
         }
       }
       return componentManager;
     }

   @CallSuper
   @Override
   public void onCreate() {
     inject();
     super.onCreate();
   }

	 @Override
     public final Object generatedComponent() {
       return this.componentManager().generatedComponent();
     }

}

AndroidEntryPoint修饰的View生成类

AndroidEntryPoint修饰的View实现类生成代码如下:

//A generated base class to be extended by the @AndroidEntryPoint annotated class. If using the Gradle plugin, this is swapped as the base class via bytecode transformation.
@Generated("ViewGenerator")
abstract class Hilt_$CLASS extends $BASE implements GeneratedComponentManagerHolder {

	private boolean injected;

 	protected void inject() {
       if (!injected) {
          (($CLASS_GeneratedInjector)this.generatedComponent()).inject$CLASS(($CLASS) this);
         injected = true;
       }
     }

    private volatile ViewComponentManager componentManager;

 	protected ViewComponentManager createComponentManager() {
       return new ViewComponentManager(this,true);
     }

	@Override
     public ViewComponentManager componentManager() {
       
       componentManager = createComponentManager();
           
       return componentManager;
     }

    @Override
    public final Object generatedComponent() {
      return this.componentManager().generatedComponent();
    }

}

总结

我们只是使用了@AndroidEntryPoint和@HiltAndroidApp修饰。但是hilt实际给我们做了很多的工作。

你可能感兴趣的:(源码实际应用,android)