2017-01-27 3 views
1

findViewById을 사용하려하지만 경고가 나타납니다. 나는이 경고를 해결하는 데 사용 된 serveral 다른 방법을 보았지만 내 코드와 관련하여 어느 것이 옳은지 알지 못합니다. 이 상황에서이 경고를 제거하는 올바른 방법을 아는 사람 있습니까?조각에 findViewById를 선언 한 후 java.lang.NullpointerException이 발생했습니다.

메소드 호출 'findViewById를은'난 당신이 보풀이 경고에 대해 얘기하고 가정 'java.lang.NullPointerException이'

Page1Fragment.java

public class Page1Fragment extends android.support.v4.app.Fragment { 

    boolean squareState; 

    public Page1Fragment() { 

    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 

     return inflater.inflate(R.layout.fragment_page1, container, false); 
    } 

    @Override 
    public void onResume(){ 
     super.onResume(); 
     loadPreferences(); 
     displaySettings(); 
    } 

    public void loadPreferences(){ 
     SharedPreferences pref = this.getActivity().getSharedPreferences("settings", AppCompatActivity.MODE_PRIVATE); 
     squareState = pref.getBoolean("square_state", true); 
    } 

    public void displaySettings() { 
     if (squareState) { 
      getView().findViewById(R.id.blue_square).setVisibility(View.VISIBLE); 
     } else { 
      getView().findViewById(R.id.blue_square).setVisibility(View.GONE); 
     } 
    } 
} 
+0

을 방지하기 위해, 또는 onCreateView 아직라는 있었하지 않을 수도 있습니다. 프래그먼트의 뷰가 아직 작성되지 않은 경우 getView()를 호출하면 null이 리턴됩니다. 따라서 null을 확인해야합니다. –

+0

getView 메소드를 호출하는 위치를 아는 경우 (onCreateView 이후와 onDestroyView 전)에는 이러한 경고를 무시할 수 있습니다. – AnixPasBesoin

+0

@AnixPasBesoin 사실이지만,이 가정을하면 과거에 나에게 놀랄만 한 놀라움이 생겼습니다. 프래그먼트가 액티비티에 첨부 된 시점과 뷰가 생성 된 시점을 아는 것은 항상 쉬운 일은 아닙니다. 예를 들어 백그라운드 스레드에서 일부 데이터를 검색하기 위해 AsyncTask를 시작한 다음 UI를 업데이트하려고하면 사용자가 조각을 탐색했을 수 있으며 getView()는이 경우 null을 반환합니다. –

답변

0

가 발생할 수 있습니다.

조각의 수명주기 부분에 따라 onCreateView 메서드가 아직 호출되지 않았거나 없을 수도 있습니다.

조각의보기가 아직 작성되지 않은 경우 (onCreateView가 아직 호출되지 않은 경우) getView()를 호출하면 null이 반환됩니다.

따라서, 당신과 같이 널 (null)를 확인해야합니다 :

View contentView = getView(); 
if (contentView != null) { 
    contentView.findViewById(R.id.blue_square).setVisibility(View.VISIBLE); 
} 

그것은 단편 활동에 부착되고 해당 뷰가 생성되었을 때 알고 항상 쉬운 일이 아닙니다. 예를 들어 백그라운드 스레드에서 일부 데이터를 검색하기 위해 AsyncTask를 시작한 다음 UI를 업데이트하려고하면 사용자가 조각을 탐색했을 수 있으며 getView()는이 경우 null을 반환합니다.

조각 수명주기에 대한 자세한 내용은 developer.android.com의 Fragment 문서를 참조하십시오.

+0

당신의 대답은 정확 합니다만, 당신이 코드를보기 싫어하는 경향이있을 때마다 getView를 null로 체크하는 것이 좋습니다. 어쨌든 결과가 null이되지 않을 때 null 케이스를 처리하지 않는다고 생각할 수도 있습니다. – AnixPasBesoin

+0

조각을 사용하는 방법에주의를 기울이지 않기 때문에 NullPointerException을 발생시키는 것보다 추한 것이 더 낫습니다. 나는 당신이 이제까지 그 코드에 작업을하는 유일한 개발자가있을거야, 당신은 안전하게 그 코드 만 onCreateView와 onDestroyView 사이에서 호출 될 것이라는 가정을 할 수 있지만, 당신은 아마 이상 걸릴 수 있습니다 다른 사람을 가정하고 코드를 작성 싶어한다고 가정 그것을 지원하십시오. –

+0

프래그먼트 수명주기는 임의의 동작이 아닙니다. 충분히 이해하면 (그리고 복잡하지는 않습니다.) 이로 인해 결코 nullptrexception이 발생하지 않습니다. – AnixPasBesoin

0

(onCreateView 이후이고 onDestroyView 이후) getView() 메서드를 호출하는 위치를 알고 있으면 해당 경고를 무시할 수 있습니다. 이 메서드는이 두 콜백 외부에서 null을 반환합니다.

반복해서 반복적으로 확인하지 않으려면 rootViewdislplaySettings 메서드에 대한 참조로 전달해야합니다.

@Override 
public void onResume() { 
    displaySettings(getView()); // You're safe here! 
} 

단편 라이프 사이클 docs를 참조하십시오 : 다음과 같이 당신이 onResume 내부를 사용할 때 더 얻을 것이다

public void displaySettings(View rootView) { 
    if (squareState) { 
     rootView.findViewById(R.id.blue_square).setVisibility(View.VISIBLE); 
    } else { 
     rootView.findViewById(R.id.blue_square).setVisibility(View.GONE); 
    } 
} 

불평.

보너스

이 조각은에있는 라이프 사이클의 어느 부분에 따라 약간의 코드 중복

public void displaySettings(View rootView) { 
    rootView.findViewById(R.id.blue_square).setVisibility(squareState ? View.VISIBLE : View.GONE); 
} 
+0

이 코드를 사용해 보았지만 불행히도 어떤 이유로 작동하지 않습니다. 그러나 응용 프로그램이 충돌하지 않습니다. – MacaronLover

+0

방금 ​​인수로 rootView를 전달했지만 작동하지 않을 이유가 없습니다. 어떻게 사용 했습니까? – AnixPasBesoin

+0

나는 당신의 제안에 따라'displaySettings' 메서드 내에서'rootView'을 사용하지만 항목은 여전히 ​​내 환경 actvity 내에서 내 스위치를 변경에도 불구하고 사라지지 않습니다. 당신이 (TAG, 일부 log.i을 할 경우 – MacaronLover