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

안드로이드 스튜디오 - php - mysql(mariadb) 연동 질문있습니다...

0 추천

제가 구글링 해서 어떤 블로그 보면서 따라했는데 계속 빈화면이나 앱중단현상이 일어나서 질문드립니다...

php-mysql연동은 잘됩니다. 테이블생성 후 .php하면 값이 나옵니다. ㅠㅠ 밑에 사진 첨부하겠습니다..

android와 연동이 안됩니다...

안드초보린이 (120 포인트) 님이 2020년 11월 4일 질문

2개의 답변

0 추천
서버의 응답 JSON에 스트링 널값이 들어온 필드가 있는지 확인해 보세요. 이 필드가 널값이라서 String.length를 엑세스 하려다가 null pointer exception이 난건데요. JSON 파싱하시는 부분의 코드가 있다면 좀 더 정확하게 알 수 있을 것 같네요.
spark (227,470 포인트) 님이 2020년 11월 4일 답변
break point 해보니 이렇게 console에 나왔습니다..
Breakpoint reached at com.example.please.MainActivity$1GetDataJSON.onPostExecute(MainActivity.java:108)
{"result":[{"id":"27","name":"hakk","address":"KOR"},{"id":"63","name":"bong","address":"KOR"},{"id":"58","name":"kang","address":"KOR"}]}
W/System.err: org.json.JSONException: No value for Age
W/System.err:     at org.json.JSONObject.get(JSONObject.java:392)
W/System.err:     at org.json.JSONObject.getString(JSONObject.java:553)
W/System.err:     at com.example.please.MainActivity.showList(MainActivity.java:55)
W/System.err:     at com.example.please.MainActivity$1GetDataJSON.onPostExecute(MainActivity.java:109)
W/System.err:     at com.example.please.MainActivity$1GetDataJSON.onPostExecute(MainActivity.java:77)
W/System.err:     at android.os.AsyncTask.finish(AsyncTask.java:695)
W/System.err:     at android.os.AsyncTask.access$600(AsyncTask.java:180)
W/System.err:     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:106)
W/System.err:     at android.os.Looper.loop(Looper.java:214)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7073)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
Breakpoint reached at com.example.please.MainActivity$1GetDataJSON.onPostExecute(MainActivity.java:109)
voidBreakpoint reached at com.example.please.MainActivity$1GetDataJSON.onPostExecute(MainActivity.java:108)
{"result":[{"id":"27","name":"hakk","address":"KOR"},{"id":"63","name":"bong","address":"KOR"},{"id":"58","name":"kang","address":"KOR"}]}
W/System.err: org.json.JSONException: No value for Age
W/System.err:     at org.json.JSONObject.get(JSONObject.java:392)
W/System.err:     at org.json.JSONObject.getString(JSONObject.java:553)
W/System.err:     at com.example.please.MainActivity.showList(MainActivity.java:55)
W/System.err:     at com.example.please.MainActivity$1GetDataJSON.onPostExecute(MainActivity.java:109)
W/System.err:     at com.example.please.MainActivity$1GetDataJSON.onPostExecute(MainActivity.java:77)
W/System.err:     at android.os.AsyncTask.finish(AsyncTask.java:695)
W/System.err:     at android.os.AsyncTask.access$600(AsyncTask.java:180)
W/System.err:     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:106)
W/System.err:     at android.os.Looper.loop(Looper.java:214)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7073)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
Breakpoint reached at com.example.please.MainActivity$1GetDataJSON.onPostExecute(MainActivity.java:109)
void
W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
W/System.err: org.json.JSONException: No value for Age
W/System.err:     at org.json.JSONObject.get(JSONObject.java:392)
W/System.err:     at org.json.JSONObject.getString(JSONObject.java:553)
W/System.err:     at com.example.please.MainActivity.showList(MainActivity.java:55)
W/System.err:     at com.example.please.MainActivity$1GetDataJSON.onPostExecute(MainActivity.java:109)
W/System.err:     at com.example.please.MainActivity$1GetDataJSON.onPostExecute(MainActivity.java:77)
W/System.err:     at android.os.AsyncTask.finish(AsyncTask.java:695)
W/System.err:     at android.os.AsyncTask.access$600(AsyncTask.java:180)
W/System.err:     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:106)
W/System.err:     at android.os.Looper.loop(Looper.java:214)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7073)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
아랫부분이 문제인듯 보여요.

@Override
            protected String doInBackground(String...params){
                String uri = params[0];
                BufferedReader bufferedReader = null;
                try{
                    URL url = new URL(uri);
                    HttpURLConnection con = (HttpURLConnection)url.openConnection();
                    StringBuilder sb = new StringBuilder();

                    bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));

                    String json;
                    while((json = bufferedReader.readLine()) != null){
                        sb.append(json+"\n");
                    }
                    return sb.toString().trim();
                }catch (Exception e){
                    return null;
                }

에러가 나면 catch 해서 null를 리턴하시잖아요? 만약 에러가 생긴다면 showList에는 null이 전달되게 됩니다.  결과적으로 JSONObject에 null을 전달하게 되어 에러가 나는 것 같네요.
JSONObject jsonObject = new JSONObject(null)

이 경우는 null인지 체크해서 null이면
 사용자에게 에러메세지를 보여주도록 설계하는 것이 좋습니다. 간단하게

@Override
            protected void onPostExecute(String result){
                 if (result == null || result.isEmpty()) {
                     showError();
                     return;
                }
                showList(result);
            }
계속 질문해서 죄송한데...
showError()를 적으니 빨간줄로 에러가 뜨는데..뭐가 문제죠ㅠㅠ.//
밑에 private void showError(){} t생성하니깐
showList(result); result부분이 빨간줄인데..뭐가 문제인가요ㅠㅠ.
옆에 빨간 전등눌러서 String 생성해주니깐 빨간줄은 안드는데 켜지자마자 꺼지거나 중단이 일어나네요ㅠㅠ
Logcat보니깐 아까랑 같은 에러가 나네요ㅕ ㅠㅠ
2020-11-04 22:26:48.367 22928-22928/? E/Zygote: isWhitelistProcess - Process is Whitelisted
2020-11-04 22:26:48.368 22928-22928/? E/Zygote: accessInfo : 1


화면에 아무것도 안뜨고 에러메시지창은 이렇게만 나오는데 뭔지 알수 있을까요ㅠ ㅠ귀찮게 해서 죄송합니다 ㅠㅠ졸작혼자해서 ㅠㅠ 도움 부탁드립니다!!ㅠㅠ
님의 에러는
{"result":[{"id":"27","name":"hakk","address":"KOR"},{"id":"63","name":"bong","address":"KOR"},{"id":"58","name":"kang","address":"KOR"}]}

W/System.err: org.json.JSONException: No value for Age

JSON 파싱에 있구요. 원인은 age 항목이 아예 빠져 있네요.  JSON 파싱 팁 중의 하나는 일단은 모든 필드가 null이 될 수 있다고 가정하는 겁니다. 아마 JSONObject에 getxxx 대신 optxxx 메소드들이 있던 걸로 기억해요. 필드가 없거나 null일 경우 쓸 수 있도록 말이죠.
훨씬 더 좋은 방법은 Gson이나 Mosh같은 JSON 라이브러리를 OkHttp + Retrofit과 함께 사용하는 겁니다. 암묵적인 업계 표준이예요. 그렇게 하면 님이 겪고 있는 문제를 훨씬 더 쉽고 강력하고 유연하게 처리할 수 있습니다.

그리고 showError()는 제가 예시로 들었기 때문에 화면에 에러 뿌리는 코드는 toast, snackbar, dialog 듣의 방법을 통해서 보여주셔야 해요.

한가지 더 중요한 사실이요, 구글이 올해 Android 11을 발표하면서 AsyncTask를 deprecated 시켰습니다. 구글플레이의 모든앱의 그 다음해 11월인가까지 최신버전의 한단께 아래버전까지 업그레이드 하게 되어있습니다. 안그러면 앱춠시가 허용되지 않습니다. 이말은 1년 지나면 AsyncTask를 이용한 코드는 더이상 사용하면 안된다는 말입니다. 그래서 제가 말했던 옵션을 고려하셔야 하는 이유입니다. 전 요즘 AsyncTask를 사용하는 개발자는 제 주변에서는 한 명도 본 적이 없어요. 그리고 테스트가 용이한 변경사항이 있을 때 쉽게 대처할 수 있는 유연한 앱을 만드시려면 앱아키텍쳐를 공부하셔야 해요. 구글이 기본적인 가이드라인을 제시하고 있고 https://developer.android.com/jetpack/guide
MVP, MVVM, MVI 등의 디자인 패턴과 Clean Architecture 라는 아키텍쳐를 많이 사용하고 있습니다. 상용앱이라면 이런 것을 도입하는 것은 아주 중요하다고 생각해요.
0 추천

JSON parsing 하실 때 null이거나 존재하지 않는 없는 필드를 읽으실 때는 주의 하셔야 해요.

https://developer.android.com/reference/org/json/JSONObject

해당 API문서를 다 확인해 보시구요. 어떻게 JSONObject이 파싱을 하는지 말해주기 때문에 아시고 사용하시라고 권장드립니다.

핵심은 서버 응답에 값이 무조건 와야 하는 필드는 getString, getInteger, getFloat, getDouble과 같은 getType()메소드를 사용해서 처리하지만, 그렇지 않고 값이 있을 수도 있고 없을 수도 있는 optional 필드의 경우는 optType(), 즉 optString, optInteger, optFloat, optDouble 같은 메소드를 이용해서 처리하셔야 해요. getType메소드는 

if no such mapping exists throws JSONException

매핑을 할 수 없을 경우 JSONException을 던지도록 되어 있습니다.  반면 optType메소드는 Exception 던지지 않아요. 따라서 getType을 사용하시려면 Exception 처리에 좀 더 신경을 쓰셔야 겠죠. getJSONArray대신에 optJSONArray를 쓰실 수 있구요.

 

 

 

spark (227,470 포인트) 님이 2020년 11월 5일 답변
...