안드로이드 앱 개발 시 실시간으로 네트워크 이미지를 불러오는 방법을 알아보겠습니다. 이 기능을 구현하기 위해 서버 구성과 클라이언트 앱 개발 두 가지 단계를 진행할 예정입니다.
서버 구축 과정에서 JSP 기반의 간단한 웹 서버를 사용했습니다. MyEclipse와 Tomcat의 설정 방법은 생략하고, 핵심적인 구성 요소를 정리하면 다음과 같습니다:
- 프로젝트 생성
- WebRoot 폴더 내에 이미지 저장용 폴더(imgServer) 생성
- 서버 실행 후 http://localhost:8080/프로젝트명/imgServer/이미지명 형식으로 접근 가능 여부 확인
클라이언트 앱에서는 최신 Android Studio를 사용하여 개발했습니다. UI 구성은 다음과 같이 설계되었습니다:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="이미지 URL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<EditText
android:id="@+id/url_input"
android:layout_width="200sp"
android:layout_height="wrap_content"
android:hint="http://example.com/image.jpg"/>
</LinearLayout>
<Button
android:id="@+id/load_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="이미지 로드"/>
<ImageView
android:id="@+id/image_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
UI 구성은 상단에 URL 입력 필드와 버튼, 하단에 이미지 표시 영역으로 나뉩니다. 주요 액티비티 코드는 다음과 같습니다:
package com.example.networkimage;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText urlInput;
private Button loadButton;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeComponents();
}
private void initializeComponents() {
urlInput = findViewById(R.id.url_input);
loadButton = findViewById(R.id.load_button);
imageView = findViewById(R.id.image_view);
loadButton.setOnClickListener(v -> {
String url = urlInput.getText().toString();
new Thread(() -> {
try {
byte[] imageData = NetworkImageFetcher.fetchImage(url);
if (imageData != null) {
runOnUiThread(() -> imageView.setImageBitmap(BitmapFactory.decodeByteArray(imageData, 0, imageData.length)));
} else {
runOnUiThread(() -> {
imageView.setImageBitmap(null);
Toast.makeText(getApplicationContext(), "잘못된 URL 형식입니다", Toast.LENGTH_SHORT).show();
});
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();
});
}
}
네트워크 요청 처리 로직은 별도의 유틸리티 클래스로 분리되어 있습니다:
package com.example.networkimage;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class NetworkImageFetcher {
public static byte[] fetchImage(String urlString) throws Exception {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.setRequestMethod("GET");
if (connection.getResponseCode() == 200) {
return StreamUtil.readStream(connection.getInputStream());
}
return null;
}
}
데이터 스트림 처리를 위한 도우미 클래스:
package com.example.networkimage;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
public class StreamUtil {
public static byte[] readStream(InputStream inputStream) throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
return outputStream.toByteArray();
}
}
최종적으로 AndroidManifest.xml에 인터넷 권한을 추가해야 합니다:
<uses-permission android:name="android.permission.INTERNET"/>
이제 앱을 실행하면 입력한 URL의 이미지를 실시간으로 표시할 수 있습니다. 네트워크 요청은 별도 스레드에서 수행되며, 결과는 메인 스레드에서 업데이트됩니다.