加载适配器时片段未附加到 Activity
Fragment not attached to Activity while loading adapter
我在第二次加载片段时遇到此错误。这很奇怪,因为第一次加载片段时没有任何问题。这是错误:
java.lang.IllegalStateException: Fragment ShopFragment{8f5d575} (89cc4724-c435-49f4-ad05-4de4f1d18fc9)} not attached to an activity.
at androidx.fragment.app.Fragment.requireActivity(Fragment.java:833)
at com.example.fragmentapp.ui.fragments.ShopFragment.onChanged(ShopFragment.java:138)
只有当我第二次打开片段时,应用程序崩溃才会发生这种情况。我从 MVVM 和 Room 开始,所以我不是这方面的专家,所以我有点迷茫。
这是我的片段中的代码
public class ShopFragment extends Fragment {
private ShopViewModel shopViewModel;
private Spinner spDeptoShop;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_shop, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
shopViewModel = new ViewModelProvider(requireActivity()).get(ShopViewModel.class);
spDeptoShop = (Spinner) view.findViewById(R.id.sp_deparmento_shop);
init();
subscribeObservers();
}
private void init() {
shopViewModel.getDeptosLocal();
}
private void subscribeObservers() {
shopViewModel.getDeptos().observe(requireActivity(), new Observer<Resource<List<Departamento>>>() {
@Override
public void onChanged(Resource<List<Departamento>> listResource) {
if(listResource != null){
Log.d(TAG, "onChanged: status: " + listResource.status);
if(listResource.data != null){
switch (listResource.status){
case LOADING:{
break;
}
case ERROR:{
Log.e(TAG, "onChanged: cannot refresh the cache." );
Log.e(TAG, "onChanged: ERROR message: " + listResource.message );
Log.e(TAG, "onChanged: status: ERROR, #DEPARTAMENTO: " + listResource.data.size());
break;
}
case SUCCESS:{
Log.d(TAG, "onChanged: cache has been refreshed.");
Log.d(TAG, "onChanged: status: SUCCESS, #DEPARTAMENTO: " + listResource.data.size());
if(listResource.data != null && listResource.data.size()>0)
{
spDeptoShop.setAdapter( new ArrayAdapter<Departamento>(requireActivity(), R.layout.spinner_list_item, listResource.data));
}
else{
}
break;
}
}
}
}
}
});
}
@Override
public void onPause() {
super.onPause();
shopViewModel.cancelRequest();
}
}
错误在行中:
spDeptoShop.setAdapter( new ArrayAdapter<Departamento>(requireActivity(), R.layout.spinner_list_item, listResource.data));
您正在使用 requireActivity()
调用 observe()
- 您的 Activity 的生命周期。这意味着您将继续接收结果,直到您的 Activity 停止 - 即,它根本不依赖于您的片段的生命周期,这意味着即使在您的片段分离后它也会继续接收结果。你不应该在片段中使用 requireActivity()
和 observe()
。
片段有一个特殊的生命周期,特别是与它们的视图创建时间相关 - getViewLifecycleOwner()
。这是你应该为你的 observe
:
使用的
shopViewModel.getDeptos().observe(getViewLifecycleOwner(), new Observer<Resource<List<Departamento>>>() {
我在第二次加载片段时遇到此错误。这很奇怪,因为第一次加载片段时没有任何问题。这是错误:
java.lang.IllegalStateException: Fragment ShopFragment{8f5d575} (89cc4724-c435-49f4-ad05-4de4f1d18fc9)} not attached to an activity.
at androidx.fragment.app.Fragment.requireActivity(Fragment.java:833)
at com.example.fragmentapp.ui.fragments.ShopFragment.onChanged(ShopFragment.java:138)
只有当我第二次打开片段时,应用程序崩溃才会发生这种情况。我从 MVVM 和 Room 开始,所以我不是这方面的专家,所以我有点迷茫。 这是我的片段中的代码
public class ShopFragment extends Fragment {
private ShopViewModel shopViewModel;
private Spinner spDeptoShop;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_shop, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
shopViewModel = new ViewModelProvider(requireActivity()).get(ShopViewModel.class);
spDeptoShop = (Spinner) view.findViewById(R.id.sp_deparmento_shop);
init();
subscribeObservers();
}
private void init() {
shopViewModel.getDeptosLocal();
}
private void subscribeObservers() {
shopViewModel.getDeptos().observe(requireActivity(), new Observer<Resource<List<Departamento>>>() {
@Override
public void onChanged(Resource<List<Departamento>> listResource) {
if(listResource != null){
Log.d(TAG, "onChanged: status: " + listResource.status);
if(listResource.data != null){
switch (listResource.status){
case LOADING:{
break;
}
case ERROR:{
Log.e(TAG, "onChanged: cannot refresh the cache." );
Log.e(TAG, "onChanged: ERROR message: " + listResource.message );
Log.e(TAG, "onChanged: status: ERROR, #DEPARTAMENTO: " + listResource.data.size());
break;
}
case SUCCESS:{
Log.d(TAG, "onChanged: cache has been refreshed.");
Log.d(TAG, "onChanged: status: SUCCESS, #DEPARTAMENTO: " + listResource.data.size());
if(listResource.data != null && listResource.data.size()>0)
{
spDeptoShop.setAdapter( new ArrayAdapter<Departamento>(requireActivity(), R.layout.spinner_list_item, listResource.data));
}
else{
}
break;
}
}
}
}
}
});
}
@Override
public void onPause() {
super.onPause();
shopViewModel.cancelRequest();
}
}
错误在行中:
spDeptoShop.setAdapter( new ArrayAdapter<Departamento>(requireActivity(), R.layout.spinner_list_item, listResource.data));
您正在使用 requireActivity()
调用 observe()
- 您的 Activity 的生命周期。这意味着您将继续接收结果,直到您的 Activity 停止 - 即,它根本不依赖于您的片段的生命周期,这意味着即使在您的片段分离后它也会继续接收结果。你不应该在片段中使用 requireActivity()
和 observe()
。
片段有一个特殊的生命周期,特别是与它们的视图创建时间相关 - getViewLifecycleOwner()
。这是你应该为你的 observe
:
shopViewModel.getDeptos().observe(getViewLifecycleOwner(), new Observer<Resource<List<Departamento>>>() {