Android:如何从网络下载图片到本地并显示到ImageView?
Hey there! I get it—finding up-to-date code examples for image downloading and loading can be tricky when old tutorials clog up search results. Let's walk through modern implementations using Picasso and Glide (two of the most actively maintained image libraries for Android) to download images from a URL to local storage and then load them into an ImageView.
First, add the latest Picasso dependency to your module-level build.gradle:
implementation 'com.squareup.picasso:picasso:2.8'
Download Image to Local Storage
Picasso doesn’t have a built-in "save to file" method, but you can use a custom Target to capture the bitmap and save it locally:
import android.graphics.Bitmap import android.os.Environment import com.squareup.picasso.Picasso import com.squareup.picasso.Target import java.io.File import java.io.FileOutputStream class ImageDownloadTarget(private val onSuccess: (File) -> Unit) : Target { override fun onBitmapLoaded(bitmap: Bitmap, from: Picasso.LoadedFrom?) { // Define save location (adjust for Android 10+ scoped storage if needed) val storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) val imageFile = File(storageDir, "picasso_download_${System.currentTimeMillis()}.jpg") try { FileOutputStream(imageFile).use { outputStream -> bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream) outputStream.flush() onSuccess(imageFile) } } catch (e: Exception) { e.printStackTrace() } } override fun onBitmapFailed(e: Exception?, errorDrawable: android.graphics.drawable.Drawable?) { e?.printStackTrace() } override fun onPrepareLoad(placeHolderDrawable: android.graphics.drawable.Drawable?) {} } // Usage in your Activity/Fragment: val imageUrl = "https://example.com/your-image.jpg" val downloadTarget = ImageDownloadTarget { savedFile -> // Image saved successfully—load it into your ImageView Picasso.get().load(savedFile).into(yourImageView) } Picasso.get().load(imageUrl).into(downloadTarget)
Key Notes
- For Android 10+ (API 29+), replace
Environment.getExternalStoragePublicDirectorywith Scoped Storage orMediaStoreto avoid permission errors. - Add required permissions to your
AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
Glide has more built-in support for local caching and file handling. Start by adding the latest dependencies:
implementation 'com.github.bumptech.glide:glide:4.16.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
Download Image to Local Storage
Use Glide’s downloadOnly method to fetch the cached file, then copy it to your desired location:
import android.os.Environment import com.bumptech.glide.Glide import com.bumptech.glide.request.target.Target import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File import java.io.FileInputStream import java.io.FileOutputStream // Helper function to download and save the image fun downloadImageWithGlide(imageUrl: String, onComplete: (File?) -> Unit) { GlobalScope.launch(Dispatchers.IO) { try { // Get Glide's cached image file val cachedFile = Glide.with(applicationContext) .download(imageUrl) .submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) .get() // Copy to your custom directory val storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) val savedFile = File(storageDir, "glide_download_${System.currentTimeMillis()}.jpg") FileInputStream(cachedFile).use { input -> FileOutputStream(savedFile).use { output -> input.copyTo(output) } } withContext(Dispatchers.Main) { onComplete(savedFile) } } catch (e: Exception) { e.printStackTrace() withContext(Dispatchers.Main) { onComplete(null) } } } } // Usage: val imageUrl = "https://example.com/your-image.jpg" downloadImageWithGlide(imageUrl) { savedFile -> savedFile?.let { // Load the saved file into your ImageView Glide.with(this) .load(it) .into(yourImageView) } }
Key Notes
- If you don’t need to save the image to a custom location (just load it into an ImageView), skip the download step and use Glide’s basic load method:
Glide.with(this) .load(imageUrl) .into(yourImageView)
- Adjust the file-saving logic for Android 10+ to comply with scoped storage rules.
Both libraries are actively maintained, so these examples should work with their latest versions. If you run into scoped storage headaches, feel free to ask for more details!
内容的提问来源于stack exchange,提问作者Abdullah Khudher

