简体   繁体   English

来自Activity的回调片段中的空指针异常

[英]Null Pointer exception in Fragment on callback from Activity

Before we go on, I know what you're thinking. 在我们继续之前,我知道你在想什么。 I initialized my object . 我初始化了我的对象 I also initialized in the appropriate method (I tried onCreateView and onResume). 我也用适当的方法初始化了(我试过onCreateView和onResume)。

My problem is an object (actually, more than one object is throwing a Null Pointer, but they are initialized in the same way) that is throwing a Null Pointer Exception and I can't, for the life of me, figure out why. 我的问题是一个对象(实际上,不止一个对象正在抛出一个空指针,但是它们以相同的方式初始化),这就是抛出一个空指针异常,而在我的生命中,我不能找出原因。

Background: I have an Activity that contains a TabHost and a ViewPager. 背景:我有一个包含TabHost和ViewPager的Activity。 The Activity is also a container for a Fragment that I have (we'll call it Frag A). Activity也是我拥有的Fragment的容器(我们称之为Frag A)。 In my Activity when Frag A is visible the user can click a button that brings up two consecutive DialogFragments. 在我的活动中,当Frag A可见时,用户可以单击一个按钮,该按钮会显示两个连续的DialogFragments。 When the second DialogFragment finishes, it calls a method from Frag A that adds some views to Frag A's layout. 当第二个DialogFragment完成时,它从Frag A调用一个方法,为Frag A的布局添加一些视图。 When the method is called, none of my objects remain initialized despite me trying to do so both in onCreateView and onResume. 当调用该方法时,尽管我在onCreateView和onResume上尝试这样做,但我的所有对象都没有保持初始化状态。

Below is applicable code: The exception is being thrown in the last method when the line wpp.addBlankExercise(); 下面是适用的代码:当行wpp.addBlankExercise();时,在最后一个方法中抛出异常wpp.addBlankExercise(); is executed. 被执行。 I'm 99% sure that it has something to do with the way the TabHost/ViewPager is using lifecycle callbacks on Frag A. I don't know exactly what part of the TabHost/ViewPager is causing this though. 我99%确定它与TabHost / ViewPager在Frag A上使用生命周期回调的方式有关。我不确切知道TabHost / ViewPager的哪个部分导致了这个问题。

Activity 活动

    static class DummyTabFactory implements TabHost.TabContentFactory {
    private final Context mContext;

    public DummyTabFactory(Context context) {
        mContext = context;
    }

    @Override
    public View createTabContent(String tag) {
        View v = new View(mContext);
        v.setMinimumWidth(0);
        v.setMinimumHeight(0);
        return v;
    }
}

public TabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager) {
    super(activity.getSupportFragmentManager());
    mContext = activity;
    mTabHost = tabHost;
    mViewPager = pager;
    mTabHost.setOnTabChangedListener(this);
    mViewPager.setAdapter(this);
    mViewPager.setOnPageChangeListener(this);
}

public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
    tabSpec.setContent(new DummyTabFactory(mContext));
    String tag = tabSpec.getTag();

    TabInfo info = new TabInfo(tag, clss, args);
    mTabs.add(info);
    mTabHost.addTab(tabSpec);
    notifyDataSetChanged();
}

@Override
public int getCount() {
    return mTabs.size();
}

@Override
public Fragment getItem(int position) {
    TabInfo info = mTabs.get(position);
    return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}

@Override
public void onTabChanged(String tabId) {
    int position = mTabHost.getCurrentTab();
    mViewPager.setCurrentItem(position);
}

@Override
public void onPageSelected(int position) {
    TabWidget widget = mTabHost.getTabWidget();
    int oldFocusability = widget.getDescendantFocusability();
    widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
    mTabHost.setCurrentTab(position);
    widget.setDescendantFocusability(oldFocusability);
}

@Override
public void getChoiceIndex(DialogFragment dialog) {
    amount = QuantityDialogFragment.amount;
    /* We keep track of which exercises are cardio exercises and which exercises are strength exercises here. If it is a cardio
    * exercise then the value is true (first choice) if it's not then the value is false (second example). */
    if (result == 0) {
        // Cardio exercise
        wpp.cardioBoolean = true;
    /* Null Pointer thrown here because the global variables that "addBlankExercise()" uses are no longer initialized. */
        wpp.addBlankExercise();
    } else {
        // Strength exercise
    // Null Pointer also thrown here for the same reason.
        wpp.cardioBoolean = false;
        wpp.addBlankExercise();
    }
}

Here's a small part of addBlankExercise() . 这是addBlankExercise()的一小部分。 It is much longer than this, but it uses the basic pattern seen here: 它比这长得多,但它使用了这里看到的基本模式:

public void addBlankExercise () {
    printLineNumber();
    System.out.println("addBlankExercise() " + getLineNumber());
    for (int i = 0; i < WorkoutPlannerActivity.amount; i++) {
        printLineNumber();
        if (isCardioList.size() == etExerciseTracker) {
        isCardioList.add(cardioBoolean);
        }
        printLineNumber();
    LinearLayout layoutInfo = new LinearLayout(context);
    layoutInfo.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
    layoutInfo.setOrientation(LinearLayout.HORIZONTAL);
    layoutInfo.setBackgroundColor(colorBlack);
    layoutInfo.setPadding(0, 0, 10, 5);

    editTextTitle = new EditText(context);
    editTextTitle.setHint("Sample Exercise");
    editTextTitle.setTextAppearance(context, R.style.style_exercise_title);
    editTextTitle.setHintTextColor(colorRed);
    editTextTitle.setBackgroundColor(colorAndroidTransparent);
    editTextTitle.setLayoutParams(new LinearLayout.LayoutParams(0, LayoutParams.WRAP_CONTENT, 12));
    editTextTitle.setTag(editTextTitle.getKeyListener());
    editTextTitle.setId(etExerciseTracker);
    etExerciseTracker ++;

Here's the stack trace: 这是堆栈跟踪:

02-08 07:26:46.082: E/AndroidRuntime(6790): FATAL EXCEPTION: main
02-08 07:26:46.082: E/AndroidRuntime(6790): java.lang.NullPointerException
02-08 07:26:46.082: E/AndroidRuntime(6790): at android.view.ViewConfiguration.get(ViewConfiguration.java:318)
02-08 07:26:46.082: E/AndroidRuntime(6790): at android.view.View.<init>(View.java:3234)
02-08 07:26:46.082: E/AndroidRuntime(6790): at android.view.ViewGroup.<init> (ViewGroup.java:420)
02-08 07:26:46.082: E/AndroidRuntime(6790): at android.widget.LinearLayout.<init> (LinearLayout.java:168)
02-08 07:26:46.082: E/AndroidRuntime(6790): at com.nutrifit.Fragments.WorkoutPlannerPopup.addBlankExercise(WorkoutPlannerPopup.java:398)
02-08 07:26:46.082: E/AndroidRuntime(6790): at com.nutrifit1.Activities.WorkoutPlannerActivity.getChoiceIndex(WorkoutPlannerActivity.java:198)
02-08 07:26:46.082: E/AndroidRuntime(6790): at com.nutrifit.Fragments.QuantityDialogFragment$1.onClick(QuantityDialogFragment.java:44)

Thanks so much in advance for your help! 非常感谢您的帮助!

The Null Pointer Exception was coming from the overridden getItem method in the TabsAdapter class. Null Pointer Exception来自TabsAdapter类中重写的getItem方法。 The problem was that the my implementation of FragmentPagerAdapter was not keeping a reference/ references to the Fragment object(s) that was being instantiated. 问题是我的FragmentPagerAdapter实现没有保留对实例化的Fragment对象的引用/引用。

For future reference: if using a TabHost and ViewPager, add a means to keep object references to Fragments being instantiated by the PagerAdapter to avoid Null Pointer Exceptions. 供将来参考:如果使用TabHost和ViewPager,添加一种方法来保持对PagerAdapter实例化Fragments的对象引用,以避免Null Pointer Exceptions。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM