일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- textview auto scroll
- 서비스
- 드로어블
- 안드로이드 스튜디오
- 안드로이드
- 프로그래밍
- 리니어 레이아웃
- edwith
- 자바
- SceneDelegate
- 제약 레이아웃
- 텍스트뷰 스크롤
- 뷰
- 데이터베이스
- 아이폰
- 코틀린
- IOS
- 테이블_레이아웃
- 수명주기
- 코드리뷰
- 스낵바
- 부스트코스
- 상대 레이아웃
- 안드로이드_프로그래밍
- 프로젝트
- 텍스트뷰 자동 스크롤
- 레이아웃
- 액션바
- RecyclerView
- Swift
- Today
- Total
듀다의 성장개발로그
[부스트코스] 안드로이드 프로그래밍 20 - Volley 본문
volley 라이브러리를 이용하면 웹으로부터 데이터를 받아오는 기능을 좀 더 간결하게 구현할 수 있습니다.
implementation 'com.android.volley:volley:1.1.0'
volley를 사용하려면 build.gradle에서 위의 코드를 implement해주어야 합니다.
public void sendImageRequest() {
String url = "https://img6.yna.co.kr/etc/inner/KR/2019/05/01/AKR20190501059500005_01_i_P2.jpg";
ImageLoadTask task = new ImageLoadTask(url, imageView);
task.execute();
}
간단하게 이미지를 불러오는 기능 먼저 시작해보겠습니다.
url로부터 이미지를 불러와서 이미지뷰에 넣는 역할을 수행하는 메소드입니다.
이 부분은 url을 불러올 뿐, 이미지를 지정해주는 클래스는 새로 만들어주어야 합니다.
AsyncTask로 만들 수 있습니다.
public class ImageLoadTask extends AsyncTask<Void, Void, Bitmap> {
private String urlStr;
private ImageView imageView;
private static HashMap<String, Bitmap> bitmapHash = new HashMap<String, Bitmap>();
public ImageLoadTask(String urlStr, ImageView imageView) {
this.urlStr = urlStr;
this.imageView = imageView;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Bitmap doInBackground(Void... voids) {
Bitmap bitmap = null;
try {
if (bitmapHash.containsKey(urlStr)) {
Bitmap oldbitmap = bitmapHash.remove(urlStr);//remove는 꺼내는 메소드
if(oldbitmap != null) {
oldbitmap.recycle();
oldbitmap = null;
}
}
URL url = new URL(urlStr);
bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
bitmapHash.put(urlStr, bitmap);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
imageView.setImageBitmap(bitmap);
imageView.invalidate();//다시 그려줌. 안해도 되지만 혹시 안그려졌을까봐
}
}
지난번에 설명한 세 가지 과정 중 doInBackground에서 이미지를 꺼내고, 끝낼 때 실행되는 onPostExecute에서 이미지를 한번 더 확인합니다.
@Override
protected Bitmap doInBackground(Void... voids) {
Bitmap bitmap = null;
try {
if (bitmapHash.containsKey(urlStr)) {
Bitmap oldbitmap = bitmapHash.remove(urlStr);//remove는 꺼내는 메소드
if(oldbitmap != null) {
oldbitmap.recycle();
oldbitmap = null;
}
}
URL url = new URL(urlStr);
bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
bitmapHash.put(urlStr, bitmap);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
좀 더 자세히 볼까요?
Bitmap 객체를 활용하는 메소드입니다.
bitmapHash에 url로부터 받아올 비트맵 이미지를 저장하는데,
비트맵을 여러 번 저장하면 메모리 공간이 낭비될 수 있기 때문에
oldbitmap이라는 Bitmap 객체에 bitmapHash에 이미 담긴 정보를 꺼냅니다.
만약 oldbitmap에 이미 정보가 담겨 있다면 비워줍니다.
recycle은 메모리를 반환하는 메소드입니다.
JSON은 웹에서 많이 사용하는 데이터 교환 형식으로, 자바스크립트 객체 포맷과 유사합니다.
보시는 것처럼 각종 데이터를 담고 있습니다.
그렇지만 이 문자열을 일일이 나눠서 필요한 정보만 가져오기에는 너무 번거롭죠.
그래서 JSON을 구글에서 구성한 GSON이라는 포맷이 있습니다.
GSON을 활용하면 JSON의 데이터를 객체로 받아올 수 있습니다,
그러면 GSON을 활용하여 객체로 받아오는 예제를 만들어보겠습니다.
데이터를 받아올 url은 http://www.kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=430156241533f1d058c603178cc3ca0e&targetDt=20120101 입니다.
링크에 접속하면 위와 같이 영화 정보가 담긴 JSON 데이터를 확인할 수 있습니다.
이 데이터를 GSON을 활용하여 객체로 받아오려고 합니다. 그러려면 어떤 객체로 받아올지 정해져야겠죠?
영화 정보를 담는 새 객체를 정의합니다.
package com.example.myvolley;
public class Movie {
String rnum;
String rank;
String rankInten;
String rankOldAndNew;
String OLDmovieCd;
String movieNm;
String openDt;
String salesAmt;
String salesShare;
String salesInten;
String salesChange;
String salesAcc;
String audiCnt;
String audiInten;
String audiChange;
String audiAcc;
String scrnCnt;
String showCnt;
}
위의 JSON의 각 데이터를 변수로 갖는 Movie클래스를 만들었습니다.
package com.example.myvolley;
import java.util.ArrayList;
public class MovieListResult {
String boxofficeType;
String showRange;
ArrayList<Movie> dailyBoxOfficeList = new ArrayList<Movie>();
}
또한, 링크에서 받아올 수 있는 데이터는 영화 한 편이 아닌 여러 편의 정보입니다. 여러 편을 다룰 수 있게 영화 목록 클래스를 새로 정의하였습니다. 그리고 영화 목록에서 다뤄지는 박스오피스 타입 변수를 정의합니다.
그리고 요청을 보낼 메소드를 정의합니다.
public void sendRequest() {
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;
}
};
StringRequest메소드에는 메소드, url, 리스너, 에러 리스너가 들어갑니다.
리스너에는 응답을 처리하는 메소드를 넣어줍니다.
그러려면 이 역할을 하는 메소드를 또 정의해주어야겠습니다.
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);
}
}
이전에 정의한 영화 목록 객체를 활용해 영화 데이터를 받아오는 메소드입니다. 박스오피스 타입에서 영화 목록 객체의 boxofficeType 변수를 접근하고, 목록의 size를 계산해 응답받은 영화 개수를 보여줍니다.
public void println(String data) {
textView.append(data+"\n");
}
그리고 화면에 표시하기 위해, 텍스트뷰에 문자열을 추가하는 println메소드를 만들어 줍니다.
버튼들이 잘 동작하고, JSON과 박스오피스 타입, 영화 개수가 잘 출력되면 앱이 제대로 동작하는 것입니다.
'안드로이드 > 부스트코스' 카테고리의 다른 글
[부스트코스] 안드로이드 프로그래밍 22 - 데이터베이스(2) (0) | 2020.03.12 |
---|---|
[부스트코스] 안드로이드 프로그래밍 21 - 데이터베이스(1) (0) | 2020.03.12 |
[부스트코스] 안드로이드 프로그래밍 - 프로젝트 D 코드 리뷰 (0) | 2020.03.06 |
[부스트코스] 안드로이드 프로그래밍 19 - 서버와 서비스 (0) | 2020.03.06 |
[부스트코스] 안드로이드 프로그래밍 18 - 스레드 (0) | 2020.03.06 |