Refactor code

main
h4h13 2020-02-05 21:14:40 +05:30
parent 016c7f6218
commit 67f4b4ecf2
4 changed files with 125 additions and 108 deletions

View File

@ -11,7 +11,7 @@ import retrofit2.create
import retrofit2.http.GET
import retrofit2.http.Query
import java.io.File
import java.util.*
import java.util.Locale
private const val BASE_QUERY_ARTIST = "search/artist"
private const val BASE_URL = "https://api.deezer.com/"
@ -20,30 +20,30 @@ interface DeezerApiService {
@GET("$BASE_QUERY_ARTIST&limit=1")
fun getArtistImage(
@Query("q") artistName: String
@Query("q") artistName: String
): Call<DeezerResponse>
companion object {
operator fun invoke(
client: okhttp3.Call.Factory
client: okhttp3.Call.Factory
): DeezerApiService {
return Retrofit.Builder()
.baseUrl(BASE_URL)
.callFactory(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create()
.baseUrl(BASE_URL)
.callFactory(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create()
}
fun createDefaultOkHttpClient(
context: Context
context: Context
): OkHttpClient.Builder =
OkHttpClient.Builder()
.cache(createDefaultCache(context))
.addInterceptor(createCacheControlInterceptor())
OkHttpClient.Builder()
.cache(createDefaultCache(context))
.addInterceptor(createCacheControlInterceptor())
private fun createDefaultCache(
context: Context
context: Context
): Cache? {
val cacheDir = File(context.applicationContext.cacheDir.absolutePath, "/okhttp-deezer/")
if (cacheDir.mkdir() or cacheDir.isDirectory) {
@ -55,12 +55,13 @@ interface DeezerApiService {
private fun createCacheControlInterceptor(): Interceptor {
return Interceptor { chain ->
val modifiedRequest = chain.request().newBuilder()
.addHeader("Cache-Control",
String.format(
Locale.getDefault(),
"max-age=31536000, max-stale=31536000"
)
).build()
.addHeader(
"Cache-Control",
String.format(
Locale.getDefault(),
"max-age=31536000, max-stale=31536000"
)
).build()
chain.proceed(modifiedRequest)
}
}

View File

@ -3,29 +3,29 @@ package code.name.monkey.retromusic.deezer
import com.google.gson.annotations.SerializedName
data class Data(
val id: String,
val link: String,
val name: String,
@SerializedName("nb_album")
val nbAlbum: Int,
@SerializedName("nb_fan")
val nbFan: Int,
val picture: String,
@SerializedName("picture_big")
val pictureBig: String,
@SerializedName("picture_medium")
val pictureMedium: String,
@SerializedName("picture_small")
val pictureSmall: String,
@SerializedName("picture_xl")
val pictureXl: String,
val radio: Boolean,
val tracklist: String,
val type: String
val id: String,
val link: String,
val name: String,
@SerializedName("nb_album")
val nbAlbum: Int,
@SerializedName("nb_fan")
val nbFan: Int,
val picture: String,
@SerializedName("picture_big")
val pictureBig: String,
@SerializedName("picture_medium")
val pictureMedium: String,
@SerializedName("picture_small")
val pictureSmall: String,
@SerializedName("picture_xl")
val pictureXl: String,
val radio: Boolean,
val tracklist: String,
val type: String
)
data class DeezerResponse(
val data: List<Data>,
val next: String,
val total: Int
val data: List<Data>,
val next: String,
val total: Int
)

View File

@ -16,9 +16,15 @@ package code.name.monkey.retromusic.glide;
import android.content.Context;
import android.graphics.Bitmap;
import androidx.annotation.NonNull;
import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.glide.artistimage.ArtistImage;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
import code.name.monkey.retromusic.model.Artist;
import code.name.monkey.retromusic.util.ArtistSignatureUtil;
import code.name.monkey.retromusic.util.CustomArtistImageUtil;
import com.bumptech.glide.BitmapRequestBuilder;
import com.bumptech.glide.DrawableRequestBuilder;
import com.bumptech.glide.DrawableTypeRequest;
@ -29,68 +35,32 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.target.Target;
import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.glide.artistimage.ArtistImage;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
import code.name.monkey.retromusic.model.Artist;
import code.name.monkey.retromusic.util.ArtistSignatureUtil;
import code.name.monkey.retromusic.util.CustomArtistImageUtil;
public class ArtistGlideRequest {
public static final int DEFAULT_ANIMATION = android.R.anim.fade_in;
private static final DiskCacheStrategy DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.SOURCE;
private static final int DEFAULT_ERROR_IMAGE = R.drawable.default_artist_art;
public static DrawableTypeRequest createBaseRequest(RequestManager requestManager, Artist artist, boolean noCustomImage, boolean forceDownload) {
boolean hasCustomImage = CustomArtistImageUtil.Companion.getInstance(App.Companion.getContext()).hasCustomArtistImage(artist);
if (noCustomImage || !hasCustomImage) {
return requestManager.load(new ArtistImage(artist.getName(), forceDownload));
} else {
return requestManager.load(CustomArtistImageUtil.getFile(artist));
}
}
public static Key createSignature(Artist artist) {
return ArtistSignatureUtil.getInstance(App.Companion.getContext()).getArtistSignature(artist.getName());
}
public static class Builder {
final RequestManager requestManager;
final Artist artist;
boolean noCustomImage;
boolean forceDownload;
boolean noCustomImage;
final RequestManager requestManager;
public static Builder from(@NonNull RequestManager requestManager, Artist artist) {
return new Builder(requestManager, artist);
}
private Builder(@NonNull RequestManager requestManager, Artist artist) {
this.requestManager = requestManager;
this.artist = artist;
}
public static Builder from(@NonNull RequestManager requestManager, Artist artist) {
return new Builder(requestManager, artist);
}
public PaletteBuilder generatePalette(Context context) {
return new PaletteBuilder(this, context);
}
public BitmapBuilder asBitmap() {
return new BitmapBuilder(this);
}
public Builder noCustomImage(boolean noCustomImage) {
this.noCustomImage = noCustomImage;
return this;
}
public Builder forceDownload(boolean forceDownload) {
this.forceDownload = forceDownload;
return this;
}
public DrawableRequestBuilder<GlideDrawable> build() {
//noinspection unchecked
return createBaseRequest(requestManager, artist, noCustomImage, forceDownload)
@ -101,9 +71,24 @@ public class ArtistGlideRequest {
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.signature(createSignature(artist));
}
public Builder forceDownload(boolean forceDownload) {
this.forceDownload = forceDownload;
return this;
}
public PaletteBuilder generatePalette(Context context) {
return new PaletteBuilder(this, context);
}
public Builder noCustomImage(boolean noCustomImage) {
this.noCustomImage = noCustomImage;
return this;
}
}
public static class BitmapBuilder {
private final Builder builder;
public BitmapBuilder(Builder builder) {
@ -112,7 +97,8 @@ public class ArtistGlideRequest {
public BitmapRequestBuilder<?, Bitmap> build() {
//noinspection unchecked
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage, builder.forceDownload)
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage,
builder.forceDownload)
.asBitmap()
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
@ -124,7 +110,9 @@ public class ArtistGlideRequest {
}
public static class PaletteBuilder {
final Context context;
private final Builder builder;
public PaletteBuilder(Builder builder, Context context) {
@ -134,7 +122,8 @@ public class ArtistGlideRequest {
public BitmapRequestBuilder<?, BitmapPaletteWrapper> build() {
//noinspection unchecked
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage, builder.forceDownload)
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage,
builder.forceDownload)
.asBitmap()
.transcode(new BitmapPaletteTranscoder(context), BitmapPaletteWrapper.class)
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
@ -145,6 +134,30 @@ public class ArtistGlideRequest {
.signature(createSignature(builder.artist));
}
}
private static final int DEFAULT_ANIMATION = android.R.anim.fade_in;
private static final DiskCacheStrategy DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.SOURCE;
private static final int DEFAULT_ERROR_IMAGE = R.drawable.default_artist_art;
@NonNull
public static Key createSignature(@NonNull Artist artist) {
return ArtistSignatureUtil.getInstance(App.Companion.getContext()).getArtistSignature(artist.getName());
}
@NonNull
private static DrawableTypeRequest createBaseRequest(@NonNull RequestManager requestManager,
@NonNull Artist artist,
boolean noCustomImage, boolean forceDownload) {
boolean hasCustomImage = CustomArtistImageUtil.Companion.getInstance(App.Companion.getContext())
.hasCustomArtistImage(artist);
if (noCustomImage || !hasCustomImage) {
return requestManager.load(new ArtistImage(artist.getName()));
} else {
return requestManager.load(CustomArtistImageUtil.getFile(artist));
}
}
}
/**

View File

@ -32,16 +32,15 @@ import java.io.IOException
import java.io.InputStream
import java.util.concurrent.TimeUnit
class ArtistImage(val artistName: String, val skipOkHttpCache: Boolean)
class ArtistImage(val artistName: String)
class ArtistImageFetcher(
private val context: Context,
private val deezerApiService: DeezerApiService,
val model: ArtistImage,
val urlLoader: ModelLoader<GlideUrl, InputStream>,
val width: Int,
val height: Int
private val context: Context,
private val deezerApiService: DeezerApiService,
val model: ArtistImage,
val urlLoader: ModelLoader<GlideUrl, InputStream>,
val width: Int,
val height: Int
) : DataFetcher<InputStream> {
private var urlFetcher: DataFetcher<InputStream>? = null
@ -96,9 +95,9 @@ class ArtistImageFetcher(
}
class ArtistImageLoader(
val context: Context,
private val deezerApiService: DeezerApiService,
private val urlLoader: ModelLoader<GlideUrl, InputStream>
val context: Context,
private val deezerApiService: DeezerApiService,
private val urlLoader: ModelLoader<GlideUrl, InputStream>
) : StreamModelLoader<ArtistImage> {
override fun getResourceFetcher(model: ArtistImage, width: Int, height: Int): DataFetcher<InputStream> {
@ -107,22 +106,27 @@ class ArtistImageLoader(
}
class Factory(
val context: Context
val context: Context
) : ModelLoaderFactory<ArtistImage, InputStream> {
private var deezerApiService: DeezerApiService
private var okHttpFactory: OkHttpUrlLoader.Factory
init {
okHttpFactory = OkHttpUrlLoader.Factory(OkHttpClient.Builder()
okHttpFactory = OkHttpUrlLoader.Factory(
OkHttpClient.Builder()
.connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.build())
deezerApiService = DeezerApiService.invoke(DeezerApiService.createDefaultOkHttpClient(context)
.build()
)
deezerApiService = DeezerApiService.invoke(
DeezerApiService.createDefaultOkHttpClient(context)
.connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.build())
.build()
)
}
override fun build(context: Context?, factories: GenericLoaderFactory?): ModelLoader<ArtistImage, InputStream> {
@ -137,5 +141,4 @@ class Factory(
// we need these very low values to make sure our artist image loading calls doesn't block the image loading queue
private const val TIMEOUT: Long = 700
}
}