ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 안드로이드 httpUrlConnection, Volley
    Android/AndroidStudio 2018. 12. 3. 16:38

    HttpURLConnetion

     이제는 웹서버에 연결하는 방식입니다. 이전까지 소켓을 통해서 서버를 만들어서 요청을 보냈는데요. 이제는 웹서버를 사용하겠습니다. 웹은 Http라는 통신규약을 사용합니다. 자바에서 웹에 요청을 보내는 api는 HttpURLConnetion입니다.  마찬가지로 쓰레드에서 웹에 요청을 보내기 때문에 view에 접근하려면 메인쓰레드에 접근하기 위해서 handler를 사용해야합니다.(뒤에 이와같은 방법을 통합한 api가 volley 입니다.)

     먼저 thread 클래스를 정의 하고 URL 객체를 받아옵니다. URL 객체에서 openConnction() 메소드를 호출하여 HttpURLConnection 객체를 얻어옵니다.

    HttpURLConnection 객체를 받아와 setConnectionTimeout(int time)-응답이없으면연결을 끝는 메소도, setRequestMethod(String st)-요청하는 방법 get과 post중 선택, setDoInput(Boolean bl), setDoOutput(Boolean bl) input과 output을 받아오는 메소드 등 초기 설정을 해줍니다. 

     HttpURLConnection 객체의 getResponseCode()를 확인하면 응답코드에 따라(http 규약에 미리 정의된 숫자) 다른 반응을 보여줄수 있습니다. getInputStream() 메소드를 통해서 응답을 받아와 BufferedReader 객체에 넣어줍니다.(바이트가 아닌 String값으로 읽어올수 있습다.)]


    class RequestThread extends Thread{
    @Override
    public void run() {



    try {
    URL url = new URL(urlStr);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    if(conn != null){
    conn.setConnectTimeout(10000);
    conn.setRequestMethod("GET");
    conn.setDoInput(true);
    conn.setDoOutput(true);

    int resCode = conn.getResponseCode(); //연결됨

    // if(resCode == HttpURLConnection.HTTP_OK) // 제대로 연결됬는지 확인할 수 있음

    BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    String line = null;
    while(true){
    line = reader.readLine();
    if(line == null){
    break;
    }

    println(line);
    }

    reader.close();
    conn.disconnect();
    }

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


     

    Volley

     앞에서 HttpURLConncetion 객체를 생성하여 웹과 연결하였습니다. 이때 쓰레드를 사용하기 때문에 Handler 객체를 사용해야하는 불편함이 있어 이를 통합한 것이 Volley api입니다. 먼저 볼리는 외브라이브러리이기 때문에 추가해주어야 합니다. build.gradle에 추가해주어야합니다.


    implementation 'com.android.volley:volley:1.1.0'


    Volley의 형식



    위 이미지는 Volley의 작동방식을 나타냅니다.


    먼저 Request객체를 생성합니다. ( 코드에서는 StringRequest를 호출하였습니다.)

    4개의 파라미터를 보냅니다. GET 또는 POST, url String, Response.Listener, Response.ErrorListener()입니다.

    순서대로 http 데이터를 보내는 방식과 용청하고자 하는 url( URL 객체가 아닌 String 값입니다) 그리고 응답을 맏았을 때 처리하는 Listener와 ErrorListener() 입니다.

    Listener는 객체를 만들어 파라미터로 보낼수 있고 무명합수로 바로 보낼수도 있습니다.


    RequestQueue객체를 Volley로 부터 받아와 위에서 만든 Request객체를 RequestQueue.add() 메소드의 파라미터로 보냅니다.



    public class MainActivity extends AppCompatActivity {
    TextView textView;
    ImageView imageView;
    ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    textView= (TextView) findViewById(R.id.textView);
    imageView = (ImageView) findViewById(R.id.imageView);
    progressBar = (ProgressBar) findViewById(R.id.progressBar);
    Button button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    sendRequest();

    }
    });


    if(AppHelper.requestQueue == null){
    AppHelper.requestQueue = Volley.newRequestQueue(getApplicationContext());
    }
    }

    public void sendRequest() {
    //String url = " http://www.google.co.kr";

    String url ="http://www.kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=430156241533f1d058c603178cc3ca0e&targetDt=20120101";

    StringRequest request = new StringRequest(
    Request.Method.GET,
    url,
    new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
    println("응답 :" + response);

    processResponse(response);
    }
    },
    new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {

    println("에러 :" + error.getMessage());
    }
    }
    ){
    @Override
    protected Map<String, String> getParams() throws AuthFailureError {
    Map<String,String> params = new HashMap<String, String>();

    return params;
    }
    }; // 세개의 파라미터를 보냈으며 params를 재정의

    request.setShouldCache(false); // Volley 자체는 캐싱을 하기때문에, 캐싱기능을 꺼버림
    AppHelper.requestQueue.add(request);
    println("요청 보냄");
    }
    }

    public class AppHelper {

    public static RequestQueue requestQueue;

    }

    RequestQueue는 다른 액티비티에서도 쓸수있도록 AppHelper 라는 클래스에 static으로 설정해 놓았습니다.




     

    JSON & GSON

    Http 프로토콜에 맞춰 데이터가 네트워크에서 전송되어집니다. 이때 데이터 포맷중에 하나가 JSON입니다. 웹에서 사용용되는 자바스크립트에서 주로 사용됩니다. 중괄혼호는 객체 이이며 콜론으로 키와 값을 구별합니다. 대괄호는 배열의 역할을 합니다. 이렇게 네트워크를 통해서 전달된 JSON 형식은 안드로이드에서 쉽게 사용할수있게 객체화하는 api가 GSON입니다.


    JSON 예시

    출처 : edwith.org



    위 JSON 예시처럼 웹에서 JSON 형태의 데이터를 받아오면 user 라는 키로 저장된 배열의 값을 객체로 만들어 안드로이드에서 사용할 수 있습다. 그 과정을 쉽게 만들어 놓은 것이 GSON api입니다. GSON을 사용하기 위해서는 먼저 api를 등록해야 합니다.


    implementation 'com.google.code.gson:gson:2.8.2'


    (gradle 파일을 수정하면 항상 snyc를 맞춰주어야합니다. gradle 파일을 손대면 나타나는 안내창에서 sync now를 눌러주면 됩니다.)



    먼저 JSON파일을 객체화 하려면 객체가 필요합니다. 위의 Json 같은 경우 user를 담고 있는 users객체가 필요하고, 배열안에 들어있는 user라는 객체가 필요할 것 같네요. 객체의 각 key 값과 value에 맞춰 변수를 선언해 줍니다. 혹시 json에서 객체를 변수로 가지고 있다면, 그렇게 설정해 주면됩니다. users라는 객체는 user라는 객체의 배열을 변수로 가지고 있으면 됩니다. 이렇게 Json에 맞춘 클래스들을 준비해 두면 Gson으로 바꾸는 방법은 간단합니다.


    먼저 Gson 객체를 만들어 줍니다.



    Gson gson = new Gson();


    그리고 fromJson() 메소드에 웹에서 받은 json형의 스트링값과, 앞에서 만든 객체를 파라미터로 넣어주변됩니다.


    MovieList movieList = gson.fromJson(response, UserList.class);

    (response는 Volley 를 통해서 웹에서 받아온 스트링 값이고, userList는 인스턴스는 json형식에 맞춘 클래스입니다.)

    만약 여러개의 객체가 있다면, 최상위 객체만 넣어주면 알아서 Gson api가 알아서 객체화 합니다.


    MainActivity.java

    public class MainActivity extends AppCompatActivity {
    TextView textView;
    ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    textView= (TextView) findViewById(R.id.textView);

    Button button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    sendRequest();

    }
    });

    Button button2 =(Button) findViewById(R.id.button2);
    button2.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    sendImageRequest();
    }
    });

    if(AppHelper.requestQueue == null){
    AppHelper.requestQueue = Volley.newRequestQueue(getApplicationContext());
    }
    }


    public void sendRequest() {
    //String url = " http://www.google.co.kr";

    String url ="";

    StringRequest request = new StringRequest(
    Request.Method.GET,
    url,
    new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
    println("응답 :" + response);

    processResponse(response);
    }
    },
    new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {

    println("에러 :" + error.getMessage());
    }
    }
    ){
    @Override
    protected Map<String, String> getParams() throws AuthFailureError {
    Map<String,String> params = new HashMap<String, String>();

    return params;
    }
    }; // 세개의 파라미터를 보냈으며 params를 재정의

    request.setShouldCache(false); // Volley 자체는 캐싱을 하기때문에, 캐싱기능을 꺼버림
    AppHelper.requestQueue.add(request);
    println("요청 보냄");
    }

    public void processResponse(String response){
    Gson gson = new Gson();
    MovieList movieList = gson.fromJson(response, MovieList.class);

    if (movieList != null){
    int countMovie = movieList.boxOfficeResult.dailyBoxOfficeList.size();
    println("박스오피스 타입 :" + movieList.boxOfficeResult.boxofficeType);
    println("응답받은 영화 개수 :" + countMovie );
    }
    }

    public void println(String data){
    textView.append(data + "\n");
    }

    }


    MovieList.java

    public class MovieList {

    MovieListResult boxOfficeResult;

    }



    MovieListResult.java

    public class MovieListResult {

    String boxofficeType;
    String showRange;

    ArrayList<Movie> dailyBoxOfficeList = new ArrayList<>();

    }


    Movie.java

    public class Movie {

    String rnum;
    String rank;
    String rankInten;
    String rankOldAndNew;
    String MovieCd;
    String MovieNm;
    String openDt;
    String salesAmt;
    String salesShare;
    String salesInten;
    String salesChange;
    String salesAcc;
    String audiCnt;
    String audiInten;
    String audiChange;
    String audiAcc;
    String srrnCnt;
    String showCnt;

    }


    'Android > AndroidStudio' 카테고리의 다른 글

    안드로이드 asynctask  (1) 2018.12.03
    커스텀 리스트뷰  (0) 2018.11.07
    MVP MVVM 모델을 활용한 안드로이드 설계  (0) 2018.10.08
    안드로이드 thread와 handler  (0) 2018.07.07
    Android Guideline  (0) 2018.07.02
Designed by Tistory.