ภาพรวม
ตัวอย่างนี้สาธิตวิธีดาวน์โหลดรูปภาพจาก URL แบบ Asynchronous ด้วย AsyncTask แสดง ProgressDialog และแสดงผลใน ImageView
ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่
สร้างโปรเจกต์ Android ใหม่ใน Android Studio
ขั้นตอนที่ 2: จัดทำ Layout (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btnDownload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ดาวน์โหลดรูปภาพ"
android:layout_margin="25dp"
android:layout_gravity="top|center_horizontal" />
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
app:layout_anchor="@id/btnDownload"
android:layout_gravity="bottom"
app:layout_anchorGravity="bottom"
android:layout_margin="10dp" />
</android.support.design.widget.CoordinatorLayout>
ขั้นตอนที่ 3: MainActivity.java
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.design.widget.CoordinatorLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.BufferedInputStream;
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 {
Context context;
Activity activity;
CoordinatorLayout coordinatorLayout;
Button button;
ProgressDialog mProgressDialog;
ImageView mImageView;
URL url;
AsyncTask mMyTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
activity = MainActivity.this;
coordinatorLayout = findViewById(R.id.coordinatorLayout);
button = findViewById(R.id.btnDownload);
mImageView = findViewById(R.id.imageView);
mProgressDialog = new ProgressDialog(activity);
mProgressDialog.setIndeterminate(true);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressDialog.setTitle("กำลังดาวน์โหลด");
mProgressDialog.setMessage("กรุณารอสักครู่ กำลังดาวน์โหลดรูปภาพ...");
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mMyTask = new DownloadTask().execute(stringToURL());
}
});
}
private class DownloadTask extends AsyncTask<URL, Void, Bitmap> {
@Override
protected void onPreExecute() {
mProgressDialog.show();
}
@Override
protected Bitmap doInBackground(URL... urls) {
URL url = urls[0];
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream inputStream = connection.getInputStream();
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
return BitmapFactory.decodeStream(bufferedInputStream);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Bitmap result) {
mProgressDialog.dismiss();
if (result != null) {
mImageView.setImageBitmap(result);
} else {
Toast.makeText(MainActivity.this, "ดาวน์โหลดล้มเหลว", Toast.LENGTH_SHORT).show();
}
}
}
protected URL stringToURL() {
try {
url = new URL("https://wallpapersite.com/images/pages/pic_w/6408.jpg");
return url;
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
}
ขั้นตอนที่ 4: AndroidManifest.xml - สิทธิ์
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
⚠️ หมายเหตุสำคัญ: AsyncTask ถูก Deprecated (API 30+)
Google แนะนำให้ใช้วิธีทันสมัยแทน:
วิธีที่ 1: Coroutines + Coil/Glide/Picasso (แนะนำมากที่สุด)
// build.gradle
implementation "io.coil-kt:coil:2.4.0"
// ใช้งาน - 1 บรรทัด!
ImageView imageView = findViewById(R.id.imageView);
ImageLoader imageLoader = ImageLoader.Builder(this).build();
imageLoader.execute(ImageRequest.Builder(this)
.data("https://example.com/image.jpg")
.target(imageView)
.build());
วิธีที่ 2: Coroutines + OkHttp (Manual)
// build.gradle
implementation "com.squareup.okhttp3:okhttp:4.11.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
// ใช้งาน
lifecycleScope.launch(Dispatchers.IO) {
try {
Request request = new Request.Builder().url(url).build();
Response response = client.newCall(request).execute();
Bitmap bitmap = BitmapFactory.decodeStream(response.body().byteStream());
withContext(Dispatchers.Main) {
imageView.setImageBitmap(bitmap);
}
} catch (IOException e) { e.printStackTrace(); }
}
วิธีที่ 3: Java - ExecutorService (ไม่ใช้ Coroutines)
ExecutorService executor = Executors.newSingleThreadExecutor();
Handler handler = new Handler(Looper.getMainLooper());
executor.execute(() -> {
try {
URL url = new URL(imageUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
Bitmap bitmap = BitmapFactory.decodeStream(conn.getInputStream());
handler.post(() -> imageView.setImageBitmap(bitmap));
} catch (IOException e) { e.printStackTrace(); }
});
บันทึกลง External Storage (ถ้าต้องการ)
// ต้องขอสิทธิ์ WRITE_EXTERNAL_STORAGE และ requestLegacyExternalStorage="true" ใน Manifest (API 29+)
File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "downloaded.jpg");
FileOutputStream fos = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush(); fos.close();
// แจ้ง MediaScanner
MediaScannerConnection.scanFile(this, new String[]{file.getAbsolutePath()}, null, null);
การทดสอบ
รันแอป กดปุ่ม "ดาวน์โหลดรูปภาพ" จะแสดง ProgressDialog แล้วแสดงรูปใน ImageView