마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

java 초보 null object reference error 질문

0 추천

첨부 이미지

로그캣에서는 이 부분이 에러가 난다고 하는데 원인을 모르겠습니다ㅜㅜ 초보라서 원인이 뭔지도 모르겠네요.

 

다음은 로그캣 전문입니다.

 

(Logcat)

2020-10-17 16:50:03.488 9840-9840/? E/city_implement: Unknown bits set in runtime_flags: 0x8000

2020-10-17 16:50:04.351 9840-9840/? E/AndroidRuntime: FATAL EXCEPTION: main

    Process: com.example.acticity_implements, PID: 9840

    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.acticity_implements/com.example.acticity_implements.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference

        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)

        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)

        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)

        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)

        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)

        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)

        at android.os.Handler.dispatchMessage(Handler.java:107)

        at android.os.Looper.loop(Looper.java:214)

        at android.app.ActivityThread.main(ActivityThread.java:7356)

        at java.lang.reflect.Method.invoke(Native Method)

        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)

        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference

        at com.example.acticity_implements.MainActivity.onCreate(MainActivity.java:15)

        at android.app.Activity.performCreate(Activity.java:7802)

        at android.app.Activity.performCreate(Activity.java:7791)

        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)

        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)

        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 

        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 

        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 

        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 

        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 

        at android.os.Handler.dispatchMessage(Handler.java:107) 

        at android.os.Looper.loop(Looper.java:214) 

        at android.app.ActivityThread.main(ActivityThread.java:7356) 

        at java.lang.reflect.Method.invoke(Native Method) 

        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 

        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

 

Buttonred에 대한 xml코드는 다음과 같습니다.

첨부 이미지

김래빗 (160 포인트) 님이 2020년 10월 17일 질문

1개의 답변

+1 추천
 
채택된 답변

android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference

에 정확한 에러 원이이 있는 것으로 보이네요. 앞에서 findViewById로 바인딩 되지 않은 뷰가 있는 것 같으니 Button들의 아이디가 정확하게 맞게 맵핑되었는지 확인하세요. 

그리고 코드가 비교적 깔끔하신 편인데, 한두가지 제안을 드리자면, Activity에 직접 Button.OnClickListenr를 구현하시는 것보다는 해당 버튼에 직접 Listener를 Java8의  Lamdba를 통해 설정하는 것이 코드를 읽기도 낫고, Button.OnClickListener가 로컬스콥으로 만들어지기 때문에 좀 더 선호된다고 할 수 있습니다. onClickListener를 모든 버튼과 공유하게 되면, 추가적으로 버튼 ID를 체크하는 로직이 들어가야 하고, 수정사항이 생길경우 이유없이 다른 버튼이 사용하고 있는 코드를 건드리게 됩니다.

private TextView colorNameText;

public void onCreate(Bundle saveInstance) {
    super.onCreate(saveInstance);

    initView();
}

private void initView() {
      colorNameText = (TextView) findViewById(R.id.textView1);

      findViewById(R.id.btnRed).setOnClickListener {
           updateTextRed();
      }

      findViewById(R.id.btnBlue).setOnClickListener {
          updateTextBlue();
      }
}

private void updateTextRed() {
    updateTextColor(R.string.red, R.color.red);
}

private void updateTextRead() {
    updateTextColor(R.string.blue, R.color.blue);
}

private void updateTextColor(@StringRes strId: Int, @ColorRes colorId: Int) {
     colorNameText.setText(strId);
     colorNameText.setTextColor(ResourceCompat.getColor(context, colorId));
}

 

spark (226,420 포인트) 님이 2020년 10월 17일 답변
김래빗님이 2020년 10월 17일 채택됨
친절하고 자세한 답변 너무 감사드립니다. 하지만 제가 너무 초보라 말씀하신 바를 잘 이해하지 못 하겠네요ㅜㅜ Stack overflow에 질문 올려보니, super.onCreate() 밑에 setcontentview(R.layout.activity_main)을 작성하라고 해서 해보니 해결이 되었습니다. 열심히 노력해서 답변자님께서 말씀하신 내용 다 알아들을 수 있도록 공부하겠습니다. 다시 한 번 친절하고 자세한 답변 감사드립니다. ^^
네. setContentView()가 빠져있었네요. 온라인상으로 에디터 없이 작성하다 보니 빠져 있었네요.
...