Memuat gambar ke ImageView dari internet tanpa library pihak ketiga


unsplash.com

Dalam membuat aplikasi Android, seorang pemrogram mau tak mau sangat tergantung dengan library pihak ketiga. Seperti retrofit yang seolah menjadi library wajib ketika aplikasi yang akan kita bikin membutuhkan koneksi ke internet. Atau Dagger ketika ingin menerapkan dependency injection.

Bahkan untuk sekadar memuat gambar pun, kita (atau saya) sangat tergantung dengan librari buatan orang di luar Google. Dalam hal muat memuat gambar, setidaknya ada tiga librari yang biasanya digunakan oleh para pengembang aplikasi. Yakni Picasso, Glide, dan sang new comer, Coil (awas typo).

Namun, apakah kita bisa membangun sebuah aplikasi Android hanya menggunakan librari bawaan SDK Android? Ya seharusnya bisa ya, dengan konsekuensi semuanya harus diselesaikan sendiri. Misal masalah pengelolaan thread, memori, dll dsb dkk.

Begitu juga dalam hal memuat gambar ke widget ImageView. Seperti zaman dahulu kala, seorang pengembang aplikasi bisa melakukan aktivitas memuat gambar tanpa menggunakan librari yang sudah sangat begitu memudahkan kita. Kalau bisa sulit, kenapa harus dipermudah, kan?

Nah, dahulu kala, ada beberapa langkah ketika kita mau memuat gambar dari url. Pertama, kita buat koneksi ke url yang dituju, lalu terima data berupa stream, setelah itu dikonversi menjadi bitmap, entah pakai BitmapFactory maupun lewat Drawable. Begini kira-kira jadinya (kode dari stackoverflow):

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
  ImageView bmImage;

  public DownloadImageTask(ImageView bmImage) {
      this.bmImage = bmImage;
  }

  protected Bitmap doInBackground(String... urls) {
      String urldisplay = urls[0];
      Bitmap mIcon11 = null;
      try {
        InputStream in = new java.net.URL(urldisplay).openStream();
        mIcon11 = BitmapFactory.decodeStream(in);
      } catch (Exception e) {
          Log.e("Error", e.getMessage());
          e.printStackTrace();
      }
      return mIcon11;
  }

  protected void onPostExecute(Bitmap result) {
      bmImage.setImageBitmap(result);
  }
}

Nanti cara pakainya begini:

new DownloadImageTask((ImageView) findViewById(R.id.imageView1))
        .execute(MY_URL_STRING);

Namun ada dua masalah. Pertama, Asynctask sudah mau pensiun. Kedua, kodenya masih pakai Java. Halo, ini 2020 dan tak afdol rasanya membikin aplikasi Android tanpa Kotlin. Untuk itu, mari kita bikin ulang fungsi seperti di atas dengan cara Kotlin. Karena Asynctask sudah mau pensiun, maka kita gunakan coroutine. Selain itu, kita gunakan salah satu fitur keren dari Kotlin, yakni extension. Jadinya kodenya kira-kira menjadi seperti ini:

@ExperimentalCoroutinesApi
fun ImageView.setImageFromUrl(url: String) {
    val scope = CoroutineScope(Dispatchers.Main)
    val view = this
    try {
        scope.launch {
            val img = loadImageUrl(url)
            view.setImageDrawable(img)
        }
    } catch (e: Exception) {
        e.printStackTrace()
        this.setImageResource(R.drawable.ic_launcher_foreground)
    }
}

@ExperimentalCoroutinesApi
suspend fun loadImageUrl(url: String): Drawable = Dispatchers.Default {
    val inputStream: InputStream = URL(url).content as InputStream
    return@Default Drawable.createFromStream(inputStream, url)
}

 

Fungsi di atas bisa disimpan di mana saja. Misalnya di berkas Extensions.kt, yang isinya kumpulan fungsi ekstensi yang bisa digunakan di manapun di proyek Android kita. Sementara cara pakainya seperti ini:

iv_image.setImageFromUrl(url)

Bagaimana pemirsa, mudah sekali bukan?


Ada komentar?

This site uses Akismet to reduce spam. Learn how your comment data is processed.