onCreate()에서 view로 접근 시 NullPointerException
조회수 2503회
이 질문은 hashcode에 빈번하게 올라오는 전형적인 질문 중에 하나입니다
튜토리얼에 따라 wizard를 사용하여 새 activity를 생성했습니다. Activity의 onCreate()내에서 View(findViewById() 메소드로 획득)를 통해 메소드 호출을 시도했는데 NullPointerException이 발생했습니다.
Activity의 onCreate():
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View something = findViewById(R.id.something);
something.setOnClickListener(new View.OnClickListener() { ... }); // NPE
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
Layout XML (fragment_main.xml):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="packagename.MainActivity$PlaceholderFragment" >
<View
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/something" />
</RelativeLayout>
1 답변
-
튜토리얼이 오래된 것으로 보이네요. Wizard가 생성하는 코드를 선호하는 fragment 기반의 UI 말고 activity 기반의 UI를 생성해보세요.
현재 view가 activity layout((activity_main.xml))이 아니라 fragment layout(fragment_main.xml)에 있습니다. Activity view hierarchy에서 해당 view를 찾기에는 앱의 라이프 사이클 상에서 onCreate()는 너무 이릅니다. 그래서 null값이 반환됐을 겁니다. Null인 상태에서 메소드 호출을 시도해서 NPE가 발생한 듯 해요.
가장 추천해드리고 싶은 방법은 코드를 fragment onCreateView()로 옮긴 후에 활성화된 fragment layout rootView에서 findViewById() 메소드를 호출하는 방법입니다.
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); View something = rootView.findViewById(R.id.something); // not activity findViewById() something.setOnClickListener(new View.OnClickListener() { ... }); return rootView; }
덧 붙이자면, fragment layout은 결국 activity view hierarchy의 일부분이 될 것이고 activity 내에서 findViewById() 메소드로도 찾을 수 있게 됩니다. 단 fragment 트랜잭션이 수행되고 난 후에 말이죠. 나머지 남겨진 fragment 트랜잭션은 onCreate()메소드가 수행된 후 super.onStart()에서 수행 됩니다.
댓글 입력