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

<왕초보> 네이버 로그인 오류입니다..

0 추천

핸드폰에서 어플을 키고 네이버 아이디로 로그인을 누르면 앱이 종료되는 오류가 발생합니다. 코드 어디를 수정해야 할까요 ㅠㅠㅠ

E/AndroidRuntime: FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to destroy activity {com.jangdonhee.matzipapp/com.nhn.android.naverlogin.ui.OAuthLoginActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.nhn.android.naverlogin.OAuthLoginHandler.run(boolean)' on a null object reference
        at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4603)
        at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4621)
        at android.app.ActivityThread.-wrap5(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1757)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6938)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.nhn.android.naverlogin.OAuthLoginHandler.run(boolean)' on a null object reference
        at com.nhn.android.naverlogin.ui.OAuthLoginActivity.onDestroy(OAuthLoginActivity.java:138)
        at android.app.Activity.performDestroy(Activity.java:7471)
        at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1255)
        at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4590)
        at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4621) 
        at android.app.ActivityThread.-wrap5(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1757) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6938) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374) 

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_mainlogin)
        binding= ActivityMainloginBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.naverLoginButton.setOnClickListener {
            mOAuthLoginModule = OAuthLogin.getInstance()
            mOAuthLoginModule.init(
                this,
                "NAVER_CLIENT_ID",
                "NAVER_CLIENT_SECRET",
                "NAVER_CLIENT_NAME"
            )
        }
            mOAuthLoginModule.startOauthLoginActivity(this, mOAuthLoginHandler);
        }


        private val mOAuthLoginHandler: OAuthLoginHandler = @SuppressLint("HandlerLeak")
        object : OAuthLoginHandler() {
            override fun run(success: Boolean) {
                if (success) {
                    val accessToken: String = mOAuthLoginModule.getAccessToken(baseContext)
                    val refreshToken: String = mOAuthLoginModule.getRefreshToken(baseContext)
                    val expiresAt: Long = mOAuthLoginModule.getExpiresAt(baseContext)
                    val tokenType: String = mOAuthLoginModule.getTokenType(baseContext)
                } else {
                    val errorCode: String = mOAuthLoginModule.getLastErrorCode(baseContext).code
                    val errorDesc: String = mOAuthLoginModule.getLastErrorDesc(baseContext)
                    Toast.makeText(
                        baseContext, "errorCode:" + errorCode
                            + ", errorDesc:" + errorDesc, Toast.LENGTH_SHORT
                        ).show()
            }
        }
    }
}
hibye (120 포인트) 님이 2021년 7월 30일 질문

1개의 답변

0 추천

네이버 SDK를 안써봐서 자세한 것은 모르겠지만, 코드에서 한가지 의문이 드는 점은

binding.naverLoginButton.setOnClickListener {
            mOAuthLoginModule = OAuthLogin.getInstance()
            mOAuthLoginModule.init(
                this,
                "NAVER_CLIENT_ID",
                "NAVER_CLIENT_SECRET",
                "NAVER_CLIENT_NAME"
            )
        }
            mOAuthLoginModule.startOauthLoginActivity(this, mOAuthLoginHandler);
        }

왜 OAuthLoginModule을 버튼을 누를 때마다 초기화를 하고 계시죠?

보통 저런 라이브러리는 어플리케이션이 실행될 때 Application 클래스 안에서 한번만 초기화를 하도록 할겁니다. 

private val mOAuthLoginModule by lazy { 
     OAuthLogin.getInstance().also { authModuel ->
           authModuel.init(
                this,
                "NAVER_CLIENT_ID",
                "NAVER_CLIENT_SECRET",
                "NAVER_CLIENT_NAME"
            )
     }
}


binding.naverLoginButton.setOnClickListener {
    mOAuthLoginModule.startOauthLoginActivity(this, mOAuthLoginHandler);
}

그리고 Button ClickListener의 코드의 scope 약간 이상합니다.

    binding.naverLoginButton.setOnClickListener {
            mOAuthLoginModule = OAuthLogin.getInstance()
            mOAuthLoginModule.init(
                this,
                "NAVER_CLIENT_ID",
                "NAVER_CLIENT_SECRET",
                "NAVER_CLIENT_NAME"
            )
    } //Endof naverLoginButton.setOnClickListener
            

     mOAuthLoginModule.startOauthLoginActivity(this, mOAuthLoginHandler);
}

private val mOAuthLoginHandler: OAuthLoginHandler = ...

 

mAuthLoginHandler는 onCreate 다음에 초기화되는 것인지 아닌지 헷갈려요. 그렇다면 당연히 NullPointer가 되겠죠.

spark (224,800 포인트) 님이 2021년 7월 30일 답변
...