📌 Intro
사용할 이미지가 적으면 프로젝트 안에 넣어서 사용해도 되지만 이미지가 많을 때는 모두 프로젝트에 넣고 실행하면 어플리케이션의 용량이 커질 것 같아 다른 방법을 생각해봐야했다. 좋은 방법을 모색하던 도중 URL을 이용하여 이미지를 받아오는 방법을 찾았고 이에 대해 정리하려 한다.
📌 권한 추가
URL을 사용한다는 것은 인터넷을 사용한다는 것이다. 즉 어플리케이션이 인터넷을 사용한다는 뜻이고 이를 위해서는 따로 권한을 추가해주어야 한다.
아래 코드를 Manifest.xml파일 application 밖에 추가하자.
<uses-permission android:name="android.permission.INTERNET"/>
추가해준 Manifest.xml 파일은 아래와 같을 것이다.
📌 코드
package com.example.imagetest;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
ImageView imageView;
Bitmap bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.imageView);
//안드로이드에서 네트워크와 관련된 작업을 할 때,
//반드시 메인 Thread가 아닌 별도의 작업 Thread를 생성하여 작업해야 한다.
Thread uThread = new Thread() {
@Override
public void run(){
try{
// 이미지 URL 경로
URL url = new URL("URL 경로");
// web에서 이미지를 가져와 ImageView에 저장할 Bitmap을 만든다.
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoInput(true); // 서버로부터 응답 수신
conn.connect(); //연결된 곳에 접속할 때 (connect() 호출해야 실제 통신 가능함)
InputStream is = conn.getInputStream(); //inputStream 값 가져오기
bitmap = BitmapFactory.decodeStream(is); // Bitmap으로 변환
}catch (MalformedURLException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
};
uThread.start(); // 작업 Thread 실행
try{
//메인 Thread는 별도의 작업 Thread가 작업을 완료할 때까지 대기해야 한다.
//join() 호출하여 별도의 작업 Thread가 종료될 때까지 메인 Thread가 기다리도록 한다.
//join() 메서드는 InterruptedException을 발생시킨다.
uThread.join();
//작업 Thread에서 이미지를 불러오는 작업을 완료한 뒤
//UI 작업을 할 수 있는 메인 Thread에서 ImageView에 이미지 지정
imageView.setImageBitmap(bitmap);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
안드로이드에서 네트워크와 관련된 작업을 할 때, 반드시 메인 Thread가 아닌 별도의 작업 Thread를 생성하여 실행해야 한다.
그렇지 않으면 NetworkOnMainThreadException을 만나게 되는데 그 이유는 안드로이드 자체에서 UI Thread(Main Thread)에게는 UI와 관련된 처리만 가능하도록 하고, 네트워크나 DB 등 리소스를 많이 필요로 하는 작업에 대해서는 차단하기 때문이다.
대신 별도의 작업 Thread에서는 UI관련 작업을 하지 못한다.
그래서 별도의 작업 Thread에서 URL을 통해 이미지를 받아오는 작업까지 진행하고, 받아온 이미지를 UI에 그려넣는 것은 UI Thread를 통해 진행하기 때문에 join을 이용하여 UI Thread(Main Thread) 기다리는 것이다.
📌 정리
안드로이드 스튜디오에서 여러개의 이미지를 사용하기 위한 방법을 찾아보았다. 직접 HttpURLConnection을 통해 보여줄 수 있지만 프로젝트에 adaptation해본 결과 굉장히 느린 속도인 것을 확인했다. 때문에 또 다른 방법을 찾아봐야했고, Glide가 해결 방법이 될 것 같다. 이에 대한 내용은 다음에 정리하도록 하겠다.
📌 참고
[1] https://blog.naver.com/PostView.nhn?blogId=hello_sail&logNo=221588839134
[2] https://readystory.tistory.com/50