如何在Fragment中使用AndroidViewModel.更重要的是,通过其他碎片在旅途中生成的碎片



Android架构组件建议使用ViewModel、LiveData、Room、Repository qualogy从本地数据库获取数据。正如Android开发者和许多其他资源所描述的那样,我正在遵循以下路径:

数据库->房间(刀(->存储库->ViewModel(AndroidViewModel(->LiveData观察员

正如它所说,Repository需要为数据库提供应用程序级上下文,这就是为什么我们使用AndroidViewModel类来创建Repository。AndroidViewModel的构造函数中需要Application对象。

现在在Fragments中,每当我使用getActivity().getApplication()时,Android Studio都会警告我,getActivity()可能返回null,而NullPointerException已生成。

我搜索了Stackflow并尝试了requireActivity().getApplication()。它奏效了。开发人员说要在onActivityCreated()方法中始终使用它。我注意到它只适用于那些由Activity创建的片段。它不适用于那些在另一个片段中创建的片段。他们从来没有接到onActivityCreated()的电话。

现在我不知道如何从这样的类访问AndroidViewModel对象。希望有人能理解这里的问题。请帮忙。

这是BranchDetailsViewModel类:

public class BranchDetailsViewModel extends AndroidViewModel {
final BranchRepository branchRepository;
final BankRepository bankRepository;
final CityRepository cityRepository;
final DistrictRepository districtRepository;
final StateRepository stateRepository;
LiveData<Branch> branch;

public BranchDetailsViewModel(Application application) {
super(application);
branchRepository = new BranchRepository(application);
bankRepository = new BankRepository(application);
cityRepository = new CityRepository(application);
districtRepository = new DistrictRepository(application);
stateRepository = new StateRepository(application);
}
}

这是BranchDetailsFragment,它是另一个Fragment的子级。目前,我正在传递Activity创建的顶级片段中的Application对象,以使其正常工作

public class BranchDetailsFragment extends Fragment {
private final Application application;
private final int branchIid;
private FragBranchDetailsBinding binding;
public BranchDetailsFragment(Application application, int branchIid) {
this.application = application;
this.branchIid = branchIid;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = FragBranchDetailsBinding.inflate(inflater, container, false);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
BranchDetailsViewModel branchDetailsViewModel = new BranchDetailsViewModel(application);
}
}

只有Repository需要上下文来查询数据库。在片段中,我们可以很容易地访问上下文。因此,在Fragment中创建Repository实例,然后将其引用传递给ViewModel,可以安全地避免内存泄漏,而不是在ViewModel中创建Repository实例。在这里,您不需要Android视图模型,因为视图模型内部不再需要上下文。

因此,在您的案例中,您可以将存储库实例从父片段传递到子片段,而不是应用程序实例,并使用ViewModel而不是AndroidViewModel。

BranchDetailsViewModel可能看起来像:

class BranchDetailsViewModel (
val branchRepository: BranchRepository,
val bankRepository: BankRepository ,
val cityRepository: CityRepository,
val districtRepository: DistrictRepository,
val stateRepository: StateRepository
) : ViewModel() {
// Do your stuff using repositories here --------
}

最新更新