以下问题:
在我的Android-App中,我使用Application-Component来实例化一个名为AppController
的类。该类用于实例化其他所谓的" Manager" -classes。
例如,DatabaseManager
用于访问SQLite数据库。
在我的活动中,我在" onCreate"方法:
mApplication = (MyApplication) getApplication();
mAppController = mApplication.getAppController();
现在,当我创建一个需要访问此AppController的片段时,因为片段的视图需要来自DatabaseManager
的一些信息。
目前我使用以下方法:
从父活动中获取AppController
onAttach(Activity activity)
,然后在片段mAppController.getDatabaseManager()
中使用onCreateViev(...)
。
此刻这似乎有效。但我已经读过onAttach(...)
中的activity-Object有时可能是null
。
这就是问题:
当null
中的活动为onAttach
时,我将无法获得DatabaseManager
,并且在设置视图时我的应用程序会崩溃。
目前我讨厌的解决方案:
目前,我唯一能想到的是检查onAttach(...)
中的活动是否为空,如果为空,则创建不在onCreateView(...)
但在onActivityCreated(...)
中的布局视图生命周期方法,因为它将100%确定活动不再是null
。
我不喜欢这种方法是我会创建片段的视图,而不是在"正确"生命周期方法,我不确定这是否有任何副作用...
我感谢每一个意见和评论:)
Siggy
答案 0 :(得分:1)
就我个人而言,我正在为此使用静态变量。
public class CustomApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
ApplicationHolder.INSTANCE.setCustomApplication(this);
}
}
然后我可以将变量放在单例枚举模式中:
public enum ApplicationHolder {
INSTANCE;
private CustomApplication customApplication = null;
public CustomApplication getCustomApplication() {
return customApplication;
}
public void setCustomApplication(CustomApplication customApplication) {
this.customApplication = customApplication;
}
}
通过这种方式,您始终可以通过
访问应用程序ApplicationHolder.INSTANCE.getCustomApplication();
然而,如果您不需要使用ProGuard 进行混淆,可以将其提升一个档次(因为Dagger 1.2.2无法正常工作)与ProGuard :( ...)
因为那时您可以使用@Provides
方法创建一个返回此应用程序的模块
@Module(complete = false, library = true)
public class ContextModule {
@Provides
public CustomApplication providesApplication() {
return ApplicationHolder.INSTANCE.getCustomApplication();
}
}
因为这样,您可以在自己的模块中为@Provides
创建AppController
方法
@Module(complete = false, library = true)
public class AppControllerModule {
@Provides
@Singleton
public AppController providesAppController(CustomApplication customApplication) {
return new AppController(customApplication);
}
}
因此,AppController需要一个构造函数,它使CustomApplication
参数初始化自己。
为了完成这项工作,您需要使用Dagger
之类的
//CustomApplication
@Override
public void onCreate() {
super.onCreate();
ApplicationHolder.INSTANCE.setCustomApplication(this);
Injector.INSTANCE.init(new RootModule());
}
RootModule的位置
@Module(
includes = {
ApplicationModule.class,
AppControllerModule.class
},
injects = {
YourFragment.class
}
)
public class RootModule {
}
Injector
是
public enum Injector
{
INSTANCE;
private ObjectGraph objectGraph = null;
public void init(final Object rootModule)
{
if(objectGraph == null)
{
objectGraph = ObjectGraph.create(rootModule);
}
else
{
objectGraph = objectGraph.plus(rootModule);
}
// Inject statics
objectGraph.injectStatics();
}
public void init(final Object rootModule, final Object target)
{
init(rootModule);
inject(target);
}
public void inject(final Object target)
{
objectGraph.inject(target);
}
public <T> T resolve(Class<T> type)
{
return objectGraph.get(type);
}
}
然后你可以做
public class YourFragment extends Fragment {
...
@Inject
AppController appController;
@Override
protected void onActivityCreated(Bundle bundle) {
super.onActivityCreated(bundle);
Injector.INSTANCE.inject(this);
}
}
有关Dagger的更多信息,请访问:https://stackoverflow.com/a/27036934/2413303
虽然我认为onCreateView
也适用于Injector
。
答案 1 :(得分:0)
为什么不在[{1}}中获取DatabaseManager
的参考资料?
答案 2 :(得分:0)
首先,你应该在onCreate()方法中创建你的视图,并在活动(以及你需要的所有东西)变得可用时用数据填充它。 此外,您可以尝试避免在Fragment中处理数据。您可以定义用于加载必要数据的界面,使您的活动实现它,并在用户执行操作时要求活动完成所有工作。你的片段只需要显示它的结果。