Reputation: 4617
I have app with Subcomponent
s like this
-------- ApplicationComponent ------------
| |
| |
| |
Service Component Activity Component
|
|
|
Fragment Component
Everything works fine, but I want to do one thing.
Android Mrequires runtime permissions so I decided to create
Controller, something like helper class that will be injected into
Fragmentor
Activity`
Common Interface
public interface PermissionController {
boolean hasPermissionInManifest(String permissionName);
boolean isPermissionGranted(String permission);
/**
* Request permission for Android 6
*
* @param permission permission that is requested
* @param requestCode request code
* @return if user is going to be asked about permission so we need to handle callback, otherwise
* user was already asked or permission is not required cause of android lower version
*/
boolean requestPermission(int requestCode, String permission);
void requestPermissions(int requestCode, String... permissions);
}
And one method from different implementations PermissionActivityManager
and PermissionFragmentManager
@Override
public boolean requestPermission(int requestCode, String permission) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (mContext.checkSelfPermission(permission)
!= PackageManager.PERMISSION_GRANTED) {
mContext.requestPermissions(new String[]{permission},
requestCode);
return true;
}
}
return false;
}
And Fragment
implementation
@Override
public boolean requestPermission(int requestCode, String permission) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(mFragment.getActivity(), permission)
!= PackageManager.PERMISSION_GRANTED) {
mFragment.requestPermissions(new String[]{permission},
requestCode);
return true;
}
}
return false;
}
Hope you got an idea.
But about the problem, my FragmentComponent
is subcomponent of ActivityComponent
They both have PermissionModule
@PerActivity
@Subcomponent(
modules = {
ActivityModule.class,
PermissionModule.class
})
public interface ActivityComponent {
Activity activity();
FragmentComponent fragmentComponent(FragmentModule module);
void inject(BaseActivity baseActivity);
void inject(MainAppActivity mainAppActivity);
}
And for Fragment
@Subcomponent(
modules = {
FragmentModule.class,
ProviderModule.class,
PermissionModule.class
})
@PerFragment
public interface FragmentComponent {
Fragment fragment();
void inject(BaseFragment baseFragment);
}
And modules are the same except annotations and returned instances.
@PerFragment
@Module
public class PermissionModule {
@PerFragment
@Provides
PermissionController providePermissionController(Fragment fragment) {
return new PermissionFragmentManager(fragment);
}
}
@PerActivity
@Module
public class PermissionModule {
@PerActivity
@Provides
PermissionController providePermissionController(Activity activity) {
return new PermissionActivityManager(activity);
}
}
So my question is - if there is any way to override provide
method used in parent component or there is another way to solve the problem ?
Because in my case PermissionActivityManager
was injected.
Upvotes: 1
Views: 2022
Reputation: 81539
@Subcomponent
inherits all bindings from the superscoped component. In this case, that is the @ActivityScope
component.
If you want to control the inherited dependencies, you have to use Component Dependencies. Component dependencies allow you to inherit only the bindings specified by the provision methods.
If you don't want to tinker with new builders, then I'd recommend using @Named("activity")
and @Named("fragment")
annotation to specify the type of permission handler you'd like to inject. You have to put it on your @Inject
annotated field and on the @Provides
annotated method.
Upvotes: 2