From 665498ec5cdcdabca4131a96acd0a3eea1215840 Mon Sep 17 00:00:00 2001 From: jhengazuji Date: Tue, 18 Nov 2025 01:50:22 +0800 Subject: [PATCH] Optimize download --- .../java/com/fongmi/android/tv/Updater.java | 4 +- .../com/fongmi/android/tv/api/EpgParser.java | 2 +- .../android/tv/api/config/WallConfig.java | 39 +++++++---- .../android/tv/player/extractor/TVBus.java | 6 +- .../com/fongmi/android/tv/utils/Download.java | 67 +++++++++---------- .../java/com/fongmi/android/tv/Updater.java | 4 +- 6 files changed, 65 insertions(+), 57 deletions(-) diff --git a/app/src/leanback/java/com/fongmi/android/tv/Updater.java b/app/src/leanback/java/com/fongmi/android/tv/Updater.java index 29c0d2e04..72ce7101e 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/Updater.java +++ b/app/src/leanback/java/com/fongmi/android/tv/Updater.java @@ -44,7 +44,7 @@ public class Updater implements Download.Callback { } public Updater() { - this.download = Download.create(getApk(), getFile(), this); + this.download = Download.create(getApk(), getFile()); } public Updater force() { @@ -96,7 +96,7 @@ public class Updater implements Download.Callback { private void confirm(View view) { view.setEnabled(false); - download.start(); + download.start(this); } private void dismiss() { diff --git a/app/src/main/java/com/fongmi/android/tv/api/EpgParser.java b/app/src/main/java/com/fongmi/android/tv/api/EpgParser.java index afa9bdcc9..0dc4cada4 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/EpgParser.java +++ b/app/src/main/java/com/fongmi/android/tv/api/EpgParser.java @@ -36,7 +36,7 @@ public class EpgParser { public static boolean start(Live live, String url) throws Exception { File file = Path.epg(Uri.parse(url).getLastPathSegment()); - Download.create(url, file).get(shouldDownload(file)); + if (shouldDownload(file)) Download.create(url, file).get(); if (file.getName().endsWith(".gz")) readGzip(live, file); else readXml(live, file); return true; diff --git a/app/src/main/java/com/fongmi/android/tv/api/config/WallConfig.java b/app/src/main/java/com/fongmi/android/tv/api/config/WallConfig.java index 64b82f810..e6e242c67 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/config/WallConfig.java +++ b/app/src/main/java/com/fongmi/android/tv/api/config/WallConfig.java @@ -18,16 +18,20 @@ import com.fongmi.android.tv.utils.FileUtil; import com.fongmi.android.tv.utils.Notify; import com.fongmi.android.tv.utils.ResUtil; import com.fongmi.android.tv.utils.UrlUtil; +import com.github.catvod.net.OkHttp; import com.github.catvod.utils.Path; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; -import java.io.InterruptedIOException; import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicInteger; public class WallConfig { + private static final String TAG = WallConfig.class.getSimpleName(); + private final AtomicInteger taskId = new AtomicInteger(0); + private Config config; private Future future; private boolean sync; @@ -64,7 +68,7 @@ public class WallConfig { } private boolean isCanceled(Throwable e) { - return e.getCause() instanceof InterruptedException || e.getCause() instanceof InterruptedIOException; + return e instanceof InterruptedException || e instanceof RuntimeException; } public void load() { @@ -72,40 +76,47 @@ public class WallConfig { } public void load(Callback callback) { + int id = taskId.incrementAndGet(); if (future != null && !future.isDone()) future.cancel(true); - future = App.submit(() -> loadConfig(callback)); + future = App.submit(() -> loadConfig(id, config, callback)); callback.start(); } - private void loadConfig(Callback callback) { + private void loadConfig(int id, Config config, Callback callback) { try { - download(); - config.update(); - RefreshEvent.wall(); - App.post(callback::success); + OkHttp.cancel(TAG); + download(id, callback); + if (taskId.get() == id) config.update(); } catch (Throwable e) { + e.printStackTrace(); if (isCanceled(e)) return; + if (taskId.get() != id) return; if (TextUtils.isEmpty(config.getUrl())) App.post(() -> callback.error("")); else App.post(() -> callback.error(Notify.getError(R.string.error_config_get, e))); Setting.putWall(1); RefreshEvent.wall(); - e.printStackTrace(); } } - private void download() throws Throwable { + private void download(int id, Callback callback) throws Throwable { File file = FileUtil.getWall(0); - Path.clear(FileUtil.getWallCache()); if (getUrl().startsWith("file")) Path.copy(Path.local(getUrl()), file); - else Download.create(UrlUtil.convert(getUrl()), file).start(); + else Download.create(UrlUtil.convert(getUrl()), file).tag(TAG).get(); if (!Path.exists(file)) throw new FileNotFoundException(); - createSnapshot(file); + if (taskId.get() != id) return; + setWallType(file); + setSnapshot(file); + RefreshEvent.wall(); + App.post(callback::success); + } + + private void setWallType(File file) { Setting.putWallType(0); if (isGif(file)) Setting.putWallType(1); else if (isVideo(file)) Setting.putWallType(2); } - private void createSnapshot(File file) throws Throwable { + private void setSnapshot(File file) throws Throwable { Bitmap bitmap = Glide.with(App.get()).asBitmap().frame(0).load(file).override(ResUtil.getScreenWidth(), ResUtil.getScreenHeight()).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE).submit().get(); try (FileOutputStream fos = new FileOutputStream(FileUtil.getWallCache())) { bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); diff --git a/app/src/main/java/com/fongmi/android/tv/player/extractor/TVBus.java b/app/src/main/java/com/fongmi/android/tv/player/extractor/TVBus.java index 3b803b902..3b98903d0 100644 --- a/app/src/main/java/com/fongmi/android/tv/player/extractor/TVBus.java +++ b/app/src/main/java/com/fongmi/android/tv/player/extractor/TVBus.java @@ -47,9 +47,9 @@ public class TVBus implements Source.Extractor, Listener { } private String getPath(String url) { - File file = new File(Path.so(), UrlUtil.path(url)); - Download.create(url, file).get(!Path.exists(file)); - return file.getAbsolutePath(); + File so = new File(Path.so(), UrlUtil.path(url)); + if (!Path.exists(so)) Download.create(url, so).get(); + return so.getAbsolutePath(); } @Override diff --git a/app/src/main/java/com/fongmi/android/tv/utils/Download.java b/app/src/main/java/com/fongmi/android/tv/utils/Download.java index 1ec43e2c9..268a57141 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/Download.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/Download.java @@ -1,5 +1,7 @@ package com.fongmi.android.tv.utils; +import android.util.Log; + import com.fongmi.android.tv.App; import com.github.catvod.net.OkHttp; import com.github.catvod.utils.Path; @@ -8,7 +10,9 @@ import com.google.common.net.HttpHeaders; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; +import java.io.IOException; import java.io.InputStream; +import java.util.concurrent.Future; import okhttp3.Response; @@ -17,71 +21,64 @@ public class Download { private final File file; private final String url; private Callback callback; + private Future future; + private String tag; public static Download create(String url, File file) { - return create(url, file, null); - } - - public static Download create(String url, File file, Callback callback) { - return new Download(url, file, callback); + return new Download(url, file); } - public Download(String url, File file, Callback callback) { + public Download(String url, File file) { + this.tag = url; this.url = url; this.file = file; - this.callback = callback; } - public File get() { - return get(true); + public Download tag(String tag) { + this.tag = tag; + return this; } - public File get(boolean force) { - if (force) performSync(); + public File get() { + doInBackground(); return file; } - public void start() { - if (url.startsWith("file")) return; - if (callback == null) performSync(); - else App.execute(this::performAsync); - } - - public void cancel() { - OkHttp.cancel(url); - Path.clear(file); - callback = null; + public void start(Callback callback) { + this.callback = callback; + future = App.submit(this::doInBackground); } - private void performSync() { - try (Response res = OkHttp.newCall(url, url).execute()) { - download(res.body().byteStream(), getLength(res)); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e.getMessage(), e); - } + public Download cancel() { + if (future != null) future.cancel(true); + OkHttp.cancel(tag); + future = null; + return this; } - private void performAsync() { - try (Response res = OkHttp.newCall(url, url).execute()) { + private void doInBackground() { + try (Response res = OkHttp.newCall(url, tag).execute()) { download(res.body().byteStream(), getLength(res)); - App.post(() -> {if (callback != null) callback.success(file);}); - } catch (Exception e) { - App.post(() -> {if (callback != null) callback.error(e.getMessage());}); + if (callback != null) App.post(() -> callback.success(file)); + } catch (IOException e) { + Path.clear(file); + if (callback != null) App.post(() -> callback.error(e.getMessage())); + else throw new RuntimeException(e.getMessage(), e); } } - private void download(InputStream is, double length) throws Exception { + private void download(InputStream is, double length) throws IOException { try (BufferedInputStream input = new BufferedInputStream(is); FileOutputStream os = new FileOutputStream(Path.create(file))) { byte[] buffer = new byte[16384]; int readBytes; long totalBytes = 0; while ((readBytes = input.read(buffer)) != -1) { + if (Thread.interrupted()) return; totalBytes += readBytes; os.write(buffer, 0, readBytes); if (length <= 0) continue; int progress = (int) (totalBytes / length * 100.0); - App.post(() -> {if (callback != null) callback.progress(progress);}); + if (callback != null) App.post(() -> callback.progress(progress)); } } } diff --git a/app/src/mobile/java/com/fongmi/android/tv/Updater.java b/app/src/mobile/java/com/fongmi/android/tv/Updater.java index 205cb714c..982e30360 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/Updater.java +++ b/app/src/mobile/java/com/fongmi/android/tv/Updater.java @@ -45,7 +45,7 @@ public class Updater implements Download.Callback { } public Updater() { - this.download = Download.create(getApk(), getFile(), this); + this.download = Download.create(getApk(), getFile()); } public Updater force() { @@ -96,7 +96,7 @@ public class Updater implements Download.Callback { private void confirm(View view) { view.setEnabled(false); - download.start(); + download.start(this); } private void dismiss() {