1

계속하기 전에, 나는 당신이 생각하는 것을 알고 있습니다. 개체를 초기화했습니다. 나는 또한 적절한 방법으로 초기화했다. (onCreateView와 onResume을 시도했다.)Null 포인터 예외에서 액티비티의 콜백 단편

내 문제는 Null Pointer Exception을 던지고있는 객체이며 실제로는 하나 이상의 객체가 Null Pointer를 던지고 있지만 Null Pointer Exception을 던지고있는 객체입니다. 이유를 찾아라.

배경 : 저는 TabHost와 ViewPager가 포함 된 활동이 있습니다. 액티비티는 내가 가지고있는 Fragment의 컨테이너이기도합니다 (Frag A라고 부름). Frag A가 보이는 내 액티비티에서 사용자는 두 개의 연속적인 DialogFragments를 가져 오는 버튼을 클릭 할 수 있습니다. 두 번째 DialogFragment가 끝나면 Frag A의 레이아웃에 몇 가지 뷰를 추가하는 Frag A의 메서드를 호출합니다. 메서드가 호출 될 때 onCreateView와 onResume에서 모두 내 객체를 초기화하려고했지만 내 객체가 초기화되지 않은 상태로 남아 있습니다.

아래 코드가 적용됩니다. wpp.addBlankExercise(); 행이 실행될 때 마지막 메서드에서 예외가 throw됩니다. 99 %는 TabHost/ViewPager가 Frag A에서 수명주기 콜백을 사용하는 방식과 관련이 있다는 것을 확신합니다. TabHost/ViewPager의 어떤 부분이이 문제를 일으키는 지 정확히 알지 못합니다.

활동

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(); 
    } 
} 

여기 addBlankExercise()의 작은 부분입니다. 그것은 이것보다 훨씬 더 오래이지만, 여기에 본 기본 패턴 사용

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) 

도와 주셔서 감사합니다 사전에 너무 많은 :

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 ++; 

여기 스택 추적의를!

+0

나는 한 가지 질문에 집중하고 예외와 함께 실제 stacktrace와 같은 관련 세부 정보를 제공하고 조각 A에서 호출하는 메서드가 어떻게 보이는지, 코드 (DialogFragment에서 호출되는 방법)를 제공합니다. 'onCreateView' 메서드를 보여주는 것은 전혀 유용하지 않습니다. – Luksprog

+0

@ Luksprog 나는 많은 사용법 중 하나라고 생각하지 않았지만 누군가가 그것을 요구할 것이라고 생각했다. :) 내 생각 엔 당신이 맞다. 내가 편집 할게. 의견을 보내 주셔서 감사합니다. – Don

+0

당신은 View를 생성하기 위해 null Context를 전달하려고한다고 생각합니다. 그러나'addBlankExercise()'에 대한 코드를 추가하지 않았을 때 우리는 단지 추측 일 뿐이라는 것을 알 수 있습니다. – Luksprog

답변

3

Null 포인터 예외가 TabsAdapter 클래스의 getItem 메서드에서 왔습니다. 문제는 FragmentPagerAdapter 구현에서 인스턴스화 된 Fragment 객체에 대한 참조/참조를 유지하지 못하는 것이 었습니다.

나중에 참조 할 경우 : TabHost 및 ViewPager를 사용하는 경우 Null 포인터 예외가 발생하지 않도록 PagerAdapter가 인스턴스화 한 Fragments에 개체 참조를 유지하는 방법을 추가하십시오.