Skip to content

Commit

Permalink
add logo cache
Browse files Browse the repository at this point in the history
  • Loading branch information
lizongying committed Jan 22, 2025
1 parent 30b9c89 commit 7409004
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 134 deletions.
11 changes: 11 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
## 更新日誌

### v1.3.8.16

* 增加LOGO緩存
* 支持設置多個EPG地址

### v1.3.8.15-kitkat

* 修復頻道記憶失敗的問題
* 打開頻道列表同時顯示組
* 增加EPG緩存

### v1.3.8.15

* 修復頻道記憶失敗的問題
Expand Down
159 changes: 96 additions & 63 deletions app/src/main/java/com/lizongying/mytv0/ImageHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,73 +3,106 @@ package com.lizongying.mytv0
import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Handler
import android.util.Log
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.lizongying.mytv0.requests.HttpClient
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File

fun loadNextUrl(
context: Context,
imageView: ImageView,
bitmap: Bitmap,
urlList: List<String>,
index: Int,
handler: Handler,
onSuccess: (Int) -> Unit
) {
if (urlList.isEmpty()) {
return
}
if (index >= urlList.size) {
return

class ImageHelper(private val context: Context) {
val cacheDir = context.cacheDir
val files: MutableMap<String, File> = mutableMapOf()

init {
val dir = File(cacheDir, LOGO)
if (!dir.exists()) {
dir.mkdir()
}
dir.listFiles()?.forEach { file ->
val name = file.name.substringBeforeLast(".")
files[name] = file
}
}
val url = urlList[index]
if (url.isEmpty()) {
Glide.with(context)
.load(bitmap)
.fitCenter()
.into(imageView)
} else {
Glide.with(context)
.load(url)
.listener(object : RequestListener<Drawable> {
override fun onResourceReady(
resource: Drawable,
model: Any,
target: Target<Drawable>?,
dataSource: DataSource,
isFirstResource: Boolean
): Boolean {
onSuccess(index)
return false
}

override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>,
isFirstResource: Boolean
): Boolean {
handler.post {
loadNextUrl(
context,
imageView,
bitmap,
urlList,
index + 1,
handler,
onSuccess
)
}
return true
private suspend fun downloadImage(url: String, file: File): Boolean {
return withContext(Dispatchers.IO) {
try {
val request = okhttp3.Request.Builder()
.url(url)
.build()

HttpClient.okHttpClient.newCall(request).execute().use { response ->
if (!response.isSuccessful) return@withContext false
response.bodyAlias()?.byteStream()?.copyTo(file.outputStream())
Log.i(TAG, "downloadImage success $url")
true
}
})
.placeholder(BitmapDrawable(context.resources, bitmap))
.fitCenter()
.into(imageView)
} catch (e: Exception) {
Log.e(TAG, "downloadImage", e)
false
}
}
}

suspend fun preloadImage(
key: String,
urlList: List<String>,
) {
val file = files[key]
if (file != null) {
Log.i(TAG, "image exists ${file.absolutePath}")
return
}

if (urlList.isEmpty()) {
return
}

for (url in urlList) {
val ext = url.substringAfterLast(".")
val file = File(cacheDir, "$LOGO/$key.$ext")
if (downloadImage(url, file)) {
Log.i(TAG, "image download success ${file.absolutePath}")
break
}
}
}

fun loadImage(
key: String,
imageView: ImageView,
bitmap: Bitmap,
url: String,
) {
val file = files[key]
if (file != null) {
Log.i(TAG, "image exists ${file.absolutePath}")
Glide.with(context)
.load(file)
.fitCenter()
.into(imageView)
return
}

if (url.isEmpty()) {
Glide.with(context)
.load(bitmap)
.fitCenter()
.into(imageView)
} else {
Glide.with(context)
.load(url)
.placeholder(BitmapDrawable(context.resources, bitmap))
.fitCenter()
.into(imageView)
}
}

companion object {
const val TAG = "ImageHelper"
const val LOGO = "logo"
}
}
}
18 changes: 7 additions & 11 deletions app/src/main/java/com/lizongying/mytv0/InfoFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import androidx.core.view.marginBottom
import androidx.core.view.marginStart
import androidx.core.view.marginTop
import androidx.fragment.app.Fragment
import com.lizongying.mytv0.Utils.getUrls
import com.lizongying.mytv0.databinding.InfoBinding
import com.lizongying.mytv0.models.TVModel

Expand Down Expand Up @@ -79,6 +78,8 @@ class InfoFragment : Fragment() {
}

val context = requireContext()
val application = context.applicationContext as MyTVApplication
val imageHelper = application.imageHelper

binding.title.text = tvModel.tv.title

Expand Down Expand Up @@ -107,17 +108,12 @@ class InfoFragment : Fragment() {
canvas.drawText(channelNum.toString(), x, y, paint)

val url = tvModel.tv.logo
val name = tvModel.tv.name
var urls =
getUrls(
"live.fanmingming.com/tv/$name.png"
) + getUrls("https://raw.githubusercontent.com/fanmingming/live/main/tv/$name.png")
if (url.isNotEmpty()) {
urls = (getUrls(url) + urls).distinct()
}
loadNextUrl(context, binding.logo, bitmap, urls, 0, handler) {
tvModel.tv.logo = urls[it]
var name = tvModel.tv.name
if (name.isEmpty()) {
name = tvModel.tv.title
}

imageHelper.loadImage(name, binding.logo, bitmap, url)
}
}

Expand Down
26 changes: 10 additions & 16 deletions app/src/main/java/com/lizongying/mytv0/ListAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.KeyEvent
import android.view.LayoutInflater
Expand All @@ -18,7 +16,6 @@ import androidx.core.content.ContextCompat
import androidx.core.view.setPadding
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.lizongying.mytv0.Utils.getUrls
import com.lizongying.mytv0.databinding.ListItemBinding
import com.lizongying.mytv0.models.TVListModel
import com.lizongying.mytv0.models.TVModel
Expand Down Expand Up @@ -187,7 +184,11 @@ class ListAdapter(

viewHolder.bindTitle(tvModel.tv.title)

viewHolder.bindImage(tvModel.tv.logo, tvModel.tv.id, tvModel.tv.name, tvModel)
var name = tvModel.tv.name
if (name.isEmpty()) {
name = tvModel.tv.title
}
viewHolder.bindImage(tvModel.tv.logo, tvModel.tv.id, name, tvModel)
}
}

Expand All @@ -196,13 +197,15 @@ class ListAdapter(
class ViewHolder(private val context: Context, val binding: ListItemBinding) :
RecyclerView.ViewHolder(binding.root) {

val handler = Handler(Looper.getMainLooper())
val application = context.applicationContext as MyTVApplication
val imageHelper = application.imageHelper


fun bindTitle(text: String) {
binding.title.text = text
}

fun bindImage(url: String?, id: Int, name: String, tvModel: TVModel) {
fun bindImage(url: String, id: Int, name: String, tvModel: TVModel) {
val width = 300
val height = 180
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
Expand All @@ -225,16 +228,7 @@ class ListAdapter(
val y = height / 2f - (paint.descent() + paint.ascent()) / 2
canvas.drawText(channelNum.toString(), x, y, paint)

var urls =
getUrls(
"live.fanmingming.com/tv/$name.png"
) + getUrls("https://raw.githubusercontent.com/fanmingming/live/main/tv/$name.png")
if (!url.isNullOrEmpty()) {
urls = (getUrls(url) + urls).distinct()
}
loadNextUrl(context, binding.icon, bitmap, urls, 0, handler) {
tvModel.tv.logo = urls[it]
}
imageHelper.loadImage(name, binding.icon, bitmap, tvModel.tv.logo)
}

fun focus(hasFocus: Boolean) {
Expand Down
Loading

0 comments on commit 7409004

Please sign in to comment.