Попытка обновить фрагмент дает NullPointerException; Я убедился, что совместимость не является проблемой, и мои фрагменты не должны быть нулевыми.

В настоящее время я пытаюсь реализовать код в своем проекте Android, где мои фрагменты будут обновляться после нажатия кнопки, воссоздавая представление и отображая различные элементы. Я убедился, что между android.app и android.support.v4.app не было проблем с совместимостью, и я уверен, что идентификаторы моих фрагментов помечены правильно.

Вот точная ошибка, которую я получил при запуске моего приложения на эмуляторе:

  java.lang.NullPointerException: Attempt to write to field 'int      android.support.v4.app.Fragment.mNextAnim' on a null object reference
        at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:722)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
        at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5257)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

И вот код Java, который вызывает проблему в своем классе:

package edu.sbu.cs.android.NMR.core;
import edu.sbu.cs.android.NMR.core.ImageAdapter;
import edu.sbu.cs.android.R;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class HomeFragment extends Fragment {
     public interface OnSelectedListener {
           public void onSelected();
      }
    OnSelectedListener mListener;
     @Override
       public void onAttach(Activity activity) {
           super.onAttach(activity);
      try {
           mListener = (OnSelectedListener) activity;
       } catch (ClassCastException e) {
           throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
       }
   }

GridView gridview;
   @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container,
     Bundle savedInstanceState) {

  View rootView = inflater.inflate(R.layout.fragment_home, container, false);
  gridview = (GridView)rootView.findViewById(R.id.gridView1);
    gridview.setAdapter(new ImageAdapter(gridview.getContext()));
    gridview.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v,
                                int position, long id) {
            ((MainActivity) getActivity()).setProblem(position);
            switch (position) {
                case 0:
                    SpectraFragment.w.loadUrl("file:///android_asset/nmr0.html");
                    getArguments().putString("problem", "0");
                    FragmentManager fragMan;
                    fragMan = getFragmentManager();
                    Fragment frg= fragMan.findFragmentById(R.layout.fragment_spectra);
                    Fragment frg2 = fragMan.findFragmentById(R.layout.fragment_questions);
                    final FragmentTransaction ft = fragMan.beginTransaction();
                    ft.detach(frg);
                    ft.attach(frg);
                    ft.detach(frg2);
                    ft.attach(frg2);
                    ft.commit();

                case 1:
                    SpectraFragment.w.loadUrl("file:///android_asset/nmr1.html");
                    getArguments().putString("problem", "1");
                    fragMan = getFragmentManager();
                    frg = fragMan.findFragmentById(R.layout.fragment_spectra);
                    frg2 = fragMan.findFragmentById(R.layout.fragment_questions);
                    final FragmentTransaction ft2 = fragMan.beginTransaction();
                    ft2.detach(frg);
                    ft2.attach(frg);
                    ft2.detach(frg2);
                    ft2.attach(frg2);
                    ft2.commit();
                case 2:
                    SpectraFragment.w.loadUrl("file:///android_asset/nmr2.html");
                    getArguments().putString("problem", "2");
                    fragMan = getFragmentManager();
                    frg = fragMan.findFragmentById(R.layout.fragment_spectra);
                    frg2 = fragMan.findFragmentById(R.layout.fragment_questions);
                    final FragmentTransaction ft3 = fragMan.beginTransaction();
                    ft3.detach(frg);
                    ft3.attach(frg);
                    ft3.detach(frg2);
                    ft3.attach(frg2);
                    ft3.commit();
                default:
                    SpectraFragment.w.loadUrl("file:///android_asset/nmr0.html");
            }

            Toast.makeText(getActivity(), " " + position, Toast.LENGTH_SHORT).show();
        }
    });
  return rootView;
   }
}

Кто-нибудь сталкивался с этой проблемой раньше, когда проблема не была связана с совместимостью между android.support.v4.app и android.app, или мне не хватает точки в моем коде, где я делаю ссылку на нулевой объект? Я искал эти форумы в течение нескольких недель и пробовал все решения, которые я мог придумать. Я даже отключил вкладки ActionBar в своей MainActivity для материального дизайна SlidingTabLayout, чтобы избавиться от проблемы совместимости, но это ничего не дало. Я разочарован тем, почему мой код не работает, и хотя я работаю с Android в течение года, все еще есть вещи, которые я не совсем понимаю, хотя я сделал другое приложение, которое отлично работает. Этот немного сложнее и был передан мне для работы, поэтому я все еще выясняю, как некоторые из них работают. Прошу прощения, что разглагольствовал, но я застрял на этом вопросе на некоторое время и, кажется, зашел в тупик. У кого-нибудь есть решения?

Кроме того, я использую студию Android для разработки своего приложения, если это имеет какое-либо значение для решения проблемы, но ранее я использовал eclipse и перенес проект.


person Alyssa    schedule 09.12.2015    source источник
comment
Это ноль. Просто примите это и отладьте.   -  person user207421    schedule 10.12.2015
comment
Я думаю, мне придется, я просто не понимаю, почему это так.   -  person Alyssa    schedule 10.12.2015


Ответы (3)


Обновление: в заявлении switch отсутствуют заявления break; по вашим делам.

Взгляните на строку 722 файла исходный код для BackStackRecord предполагает, что вы вызвали FragmentTransaction.detach() с нулевым фрагментом. Вероятно, один из ваших вызовов findFragmentById() возвращает значение null. Чтобы узнать, какой из них, проверьте результат каждого вызова и запишите отладочное сообщение, если оно равно null.

person Bob Snyder    schedule 09.12.2015
comment
Спасибо за информацию, это было полезно, мне нужно будет посмотреть исходный код в будущем, чтобы помочь мне решить эти проблемы, я попробую это. - person Alyssa; 10.12.2015

Проблема в том, что вы используете android.support.v4.app.FragmentTransaction для фрагментов, которые, вероятно, расширяют android.app.Fragment.

Вы должны использовать android.app.FragmentTransaction с android.app.Fragment, и вы должны использовать android.support.v4.app.FragmentTransaction для совершения транзакций с участием android.app.v4.app.Fragment

Вы не можете смешивать два. Чтобы это исправить, нужно просто заменить фрагменты, вызывающие нарушение, на расширение android.support.v4.app.Fragment.

person NoChinDeluxe    schedule 09.12.2015
comment
Спасибо за помощь, но я клянусь, что каждый фрагмент расширяется и импортирует фрагмент android.support.v4.app. Фактически, я заменил ActionBar.tabs, которые использовал в своей основной деятельности, потому что они не позволяли мне использовать менеджер фрагментов android.support.v4.app. - person Alyssa; 10.12.2015
comment
Это, вероятно, решение и даже было подтверждено в других вопросах mnextanim">например, этот. Это может помочь опубликовать код в других ваших фрагментах, чтобы получить еще один взгляд на них. Иногда, когда я расстраиваюсь и зацикливаюсь на конкретной проблеме, я пропускаю сделанные глупые ошибки. Это может помочь :) - person NoChinDeluxe; 10.12.2015

Ошибка ясно показывает вам, что она действовала по нулевой ссылке на объект, что означает отсутствие фрагмента с соответствующим идентификатором в этом диспетчере фрагментов. Попробуйте либо getChildFragmentManager(), либо getParentFragment(), что сработало для меня.

person RAMAKRISHNA    schedule 14.08.2017