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

스튜디오 <->php 연동간, nullpointerexception 문제..

0 추천
사실 이곳에다가만 3번째 질문하는건데요 ㅠ

도무지 에러원인을 혼자찾을수가 없어서 다시 한번 질문해봅니다..

php<->mysql연동후, android studio2.2에서 php로 db에 있는 데이터를 받아서 띄우려고 합니다.

그런데 android studio에서 데이터를 Json으로 받아오는 부분에서 계속

nullpointerexception이 납니다..

제가 혼자하다가 안되서 구글링해서 찾아봤는데

 

http://webnautes.tistory.com/829  

 

 많은 분들이 결점없다고 평가한 저 예제마저도 nullpointerexception이 나네요.

DB에 널값있는거 아니구요, JSON문법잘못된것도 아닙니다. INTERNET 퍼미션도 있구요

코드상 문제는 아닐거라고 추측되는게,

저 예제말고도 다른예제에서도 nullpointerexception이 나는걸보니 기본적인 설정의

문제인거같은데 안스나 php연동할때 별도의 설정이 필요한걸까요?

뭐가 잘못된지 아는분 계실까요..

일단 오류 내역과 코드를 댓글로 첨부하겠습니다.
익명사용자 님이 2017년 2월 2일 질문
2017년 2월 2일 수정
--------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.park.smart_shopper2, PID: 3359
                  java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
                      at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116)
                      at org.json.JSONTokener.nextValue(JSONTokener.java:94)
                      at org.json.JSONObject.<init>(JSONObject.java:156)
                      at org.json.JSONObject.<init>(JSONObject.java:173)
                      at com.example.park.smart_shopper2.MainActivity.showList(MainActivity.java:52)
                      at com.example.park.smart_shopper2.MainActivity$1GetDataJSON.onPostExecute(MainActivity.java:130)
                      at com.example.park.smart_shopper2.MainActivity$1GetDataJSON.onPostExecute(MainActivity.java:97)
                      at android.os.AsyncTask.finish(AsyncTask.java:667)
                      at android.os.AsyncTask.-wrap1(AsyncTask.java)
                      at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:684)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6119)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Application terminated.
<MainActivity>

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;



public class MainActivity extends Activity {

    String myJSON;

    private static final String TAG_RESULTS="result";
    private static final String TAG_NAME = "product_name";
    private static final String TAG_CATEGORY = "category";
    private static final String TAG_PRICE ="price";
    private static final String TAG_DATE="expiry_date";
    private static final String TAG_BARCOE="barcode_value";

    JSONArray peoples = null;

    ArrayList<HashMap<String, String>> personList;

    ListView list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        list = (ListView) findViewById(R.id.listView);
        personList = new ArrayList<HashMap<String,String>>();
        getData("http://127.0.0.1/getdata.php");
    }


    protected void showList(){
        try {
            JSONObject jsonObj = new JSONObject(myJSON);
            peoples = jsonObj.getJSONArray(TAG_RESULTS);




            for(int i=0;i<peoples.length();i++)
            {



                JSONObject c = peoples.getJSONObject(i);
                String product_name = c.getString(TAG_NAME);
                String category = c.getString(TAG_CATEGORY);
                String price = c.getString(TAG_PRICE);
                String expiry_date=c.getString(TAG_DATE);
                String barcode_value=c.getString(TAG_BARCOE);


                HashMap<String,String> persons = new HashMap<String,String>();

                persons.put(TAG_NAME, product_name);
                persons.put(TAG_CATEGORY,category);
                persons.put(TAG_PRICE, price);
                persons.put(TAG_DATE, expiry_date);
                persons.put(TAG_BARCOE, barcode_value);

                personList.add(persons);
            }

            ListAdapter adapter = new SimpleAdapter(
                    MainActivity.this, personList, R.layout.list_item,
                    new String[]{TAG_NAME,TAG_CATEGORY,TAG_PRICE,TAG_DATE,TAG_BARCOE},
                    new int[]{R.id.product_name, R.id.category, R.id.price,R.id.expiry_date, R.id.barcode_value}
            );

            list.setAdapter(adapter);

        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

    public void getData(String url){
        class GetDataJSON extends AsyncTask<String, Void, String>{

            @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;
                }



            }

            @Override
            protected void onPostExecute(String result){
                myJSON=result;
                showList();
            }
        }
        GetDataJSON g = new GetDataJSON();
        g.execute(url);
    }
<getData.php>

<?php  
 
function unistr_to_xnstr($str){
    return preg_replace('/\\\u([a-z0-9]{4})/i', "&#x\\1;", $str);
}
 
$con=mysqli_connect("127.0.0.1","root","","shop_db");  
  
if (mysqli_connect_errno($con))  
{  
   echo "Failed to connect to MySQL: " . mysqli_connect_error();  
}  
 
 
mysqli_set_charset($con,"utf8");  
 
 
$res = mysqli_query($con,"select * from product");  
   
$result = array();  
   
while($row = mysqli_fetch_array($res)){  
  array_push($result,  
    array('prodcut_name'=>$row[0],'category'=>$row[1],'price'=>$row[2],'expiry_date'=>$row[3],
          'barcode_value'=>$row[4]  
    ));  
}  
   
 
$json = json_encode(array("result"=>$result));
echo unistr_to_xnstr($json);
 
   
mysqli_close($con);  
   
?>

1개의 답변

0 추천

코드는 댓글이 아닌 http://www.masterqna.com/android/1 이 글처럼 본문에 넣으세요. 앞으로도 프로그래머를 할 거라면 또 다시 질문을 해야하는 순간이 오는데, 그 때도 지금처럼 코드가 한 눈에 안 들어오면 그 만큼 답변이 늦게 달립니다. 

https://susemi99.gitbooks.io/howto-for-beginners/content/

 


먼저 에러 로그부터 살펴보죠.

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
.
.
.
 at com.example.park.smart_shopper2.MainActivity.showList(MainActivity.java:52)
.
.

NullPointerException 은 아직 선언되지 않았거나, null 인 변수에서 무언가를 꺼내올 때 발생합니다. 친절하게 MainActivity.java의 52번째 줄에서 발생했다고 하네요. null 인 String의 길이를 구하려다보니 발생했다고 하네요.

 

그럼 MainActivity의 52번째 줄이 어디인지 보면 되겠죠? 올려주신 코드에는 안 나와있지만 아마도 

JSONObject jsonObj = new JSONObject(myJSON);

이 구문일 가능성이 제일 높습니다. 

왜냐면 try-catch 에서는 JSONException 만 잡고 NullPointerException 은 처리를 안하기 때문이죠.

 

그렇다면 52번의 어느 부분이 문제일까요?

jsonObj는 이제 생성하는 것이니 문제가 될 만한건 myJSON 밖에 없습니다. 

 

그럼 어디에서 myJSON에 값을 넣어줄까요?

protected void onPostExecute(String result){
   myJSON=result;
   showList();
}

여기 밖에 없네요.

그럼 어떻게 해야할까요?

 

이럴 때 쓰라고 있는 게 Log 입니다. 

protected void onPostExecute(String result){
  Log.i("###", "|" + result);
   myJSON=result;
   showList();
}

이렇게 바꾸면 result 가 null 이라서 myJSON도 null 인지를 확인해보면 됩니다. 

 

만약 저기서 null이면 어떻게 해야할까요?

그럴 땐 저 result가 어디서 넘어오는지를 확인해보고, 거기에서 log를 찍어보는 식으로 계속 한 단계씩 뒤로 가면서 찍어보면 됩니다.

 

앱에서는 더 이상 찍어볼 곳이 없다? 그럼 php에서 문제가 발생했겠죠. 그럼 php로 가서 찍어보면 되는 겁니다.

 

가장 기초적인 디버깅 방식입니다.

도무지 찾을 수 없다고 했지만, 다른 사람이 보기에는 눈으로만 대충 훑은 걸로 밖에 안 보입니다. 대충 훑는 방식은 고수나 천재들에게 어울리는 방식입니다. 

쎄미 (162,410 포인트) 님이 2017년 2월 3일 답변
일단 제 질문방식이 불편했으면 사과드리구요, 여태껏 로그를 찍어보긴했는데 완전 엉뚱한데다가 찍어보고 있었네요..
지적해주신 곳에 로그를 찍어봤는데 null이 나오네요. 그런데 php에서는 문제가없어요. 즉 php와 스튜디오는 개별적으로 문제가 없는데 두 개를 연동하는 과정에서 문제가 생긴거같은데 어느곳을 점검해봐야할까요?
php에서 잘 나오는지 확인을 다시 해보시고, 코드가 아닌 다른 컴퓨터의 브라우져에서도 나오는지, 인코딩 문제는 아닌지, 서버에 php가 아닌 json 파일을 읽어도 같은 문제인지,  asynctask가 아닌 retrofit 같은 걸로 해도 같은 증상인지 확인하면 되지 않을까요? retrofit으로 json 읽어오는 건 https://github.com/susemi99/RetrofitSample 에 있습니다.
...