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

API 이용해서 Volley하고 파싱하려는데

0 추천

volley 작업한 것만 출력이 되고 출력된 내용 중의 일부를 다시 파싱해서 append로 함께 출력하려고 하니 

안되네요.. 밑은 제가 작성한 코드입니다. 뭐가 문제일까요?

 

package com.example.android;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONObject;

public class MainActivity extends AppCompatActivity {
    TextView resultView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        resultView = (TextView) findViewById(R.id.textView);
        RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext()); // this도 가능
        String url="https://api.openweathermap.org/data/2.5/weather?lat=38.58&lon=126.93&appid=01b4f335cde82392f671b9c085b48c2a";
        StringRequest stringRequest = new StringRequest(Request.Method.GET,
                url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        resultView.setText("Response:\n\n" + response);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        resultView.setText("오류!");
                    }
                });
        requestQueue.add(stringRequest);

        String jsonData="{\"main\":{\"temp\":278.08,\"feels_like\":276.63,\"temp_min\":278.08},"
                +"\"wind\":{\"speed\":1.82, \"deg\":31}}";
        try{
            JSONObject jsonObject = new JSONObject(jsonData);
            JSONObject mainObject = jsonObject.getJSONObject("main");

            Double temp = mainObject.getDouble("temp");
            resultView.append("\n\n\n온도:"+temp);

            Double feels_like = mainObject.getDouble("feels_like");
            resultView.append("\n체감온도:"+feels_like);
            JSONObject windObject = jsonObject.getJSONObject("wind");

            Double speed = windObject.getDouble("speed");
            resultView.append("\n시속:"+speed);}

        catch(Exception e){e.printStackTrace();}
    }
}
희망을기억해 (200 포인트) 님이 2022년 3월 30일 질문

1개의 답변

0 추천

Synchronous(동기)와  Asynchronous(비동기)에 대해 들어보셨으리라 생각합니다. 원인은 이것 때문이고, 네트워크 라이브러리는 대부분 Async입니다. Volley의 경우는 Response.Listner의 콜백을 사용해서 결과를 받게 됩니다. Async이기 때문에 언제 결과가 올지는 알 수가 없습니다. 따라서 onCreate에서 Volley를 통해 요청을 보낸 다음, 바로 JsonData를 parsing해서 resultView에 텍스트를 추가하는 시점에 volley에서 응답이 아직 도착하지 않은 상태일 수 있습니다. 따라서 이 부부을 volley의 onResponse 메소드 안으로 옮기셔야 합니다.

public class WeatherExtraInfo {
    private final double temp;
    private final double feelsLike;
    private final double speed;
  
    // Constructor, getter 생략
}

public class MainActivity extends AppCompatActivity {
    TextView resultView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        StringRequest stringRequest = new StringRequest(Request.Method.GET,
                url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        bindWeatherResponse(response); // <--- 응답을 받고나서 모든 처리.
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        resultView.setText("오류!");
                    }
                });
        requestQueue.add(stringRequest);

    }
}

private void bindWeatherResponse(String response) {
    StriingBuilder sb = new StringBuilder("Response:\n\n").append(response);
    try. {
           WeatherExtraInfo extraInfo = parseWeatherExtraInfo();
           sb.append("\n\n\n온도:").append(extraInfo.getTemp())
               .append("\n체감온도:").append(extraInfo.getFeelsLike())
               .append("\n\n\n시속:").append(extraInfo.getSpeed());

            resultView.setText(sb.toString());
    } catch (Exception e) {
         e.printStackTrace();
    }
}

private WeatherExtraInfo parseWeatherExtraInfo() {
     String jsonData ="{\"main\":{\"temp\":278.08,\"feels_like\":276.63,\"temp_min\":278.08},"
                +"\"wind\":{\"speed\":1.82, \"deg\":31}}";
        
      JSONObject jsonObject = new JSONObject(jsonData);
      
      JSONObject mainObject = jsonObject.getJSONObject("main");
      double temp = mainObject.getDouble("temp");
      double feelsLike = mainObject.getDouble("feels_like");
     
       JSONObject windObject = jsonObject.getJSONObject("wind");
       double speed = windObject.getDouble("speed");
       
       return new WeatherExtraInfo(temp, feelsLike, speed);
}

 

spark (227,470 포인트) 님이 2022년 3월 30일 답변
spark님이 2022년 3월 30일 수정
동기 비동기 관련 문제일줄은 몰랐네요.. 이렇게 또 알아갑니다 정말 감사해요! 편안한 주말 되세요
...