From a580464c1c93f4d8c3d3fd8427f618686c75ed53 Mon Sep 17 00:00:00 2001 From: jhengazuki Date: Fri, 31 Oct 2025 01:25:03 +0800 Subject: [PATCH] Optimize vod config load --- .../tv/ui/activity/SettingActivity.java | 4 +- .../main/java/com/fongmi/android/tv/App.java | 4 + .../android/tv/api/config/VodConfig.java | 98 +++++++++++-------- .../java/com/fongmi/android/tv/bean/Site.java | 9 +- .../tv/ui/fragment/SettingFragment.java | 5 +- 5 files changed, 70 insertions(+), 50 deletions(-) diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingActivity.java index 77b619603..bcb27b90d 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingActivity.java @@ -133,6 +133,7 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit if (config.getUrl().startsWith("file")) { PermissionUtil.requestFile(this, allGranted -> load(config)); } else { + Notify.progress(this); load(config); } } @@ -140,16 +141,13 @@ public class SettingActivity extends BaseActivity implements ConfigCallback, Sit private void load(Config config) { switch (config.getType()) { case 0: - Notify.progress(this); VodConfig.load(config, getCallback(0)); break; case 1: - Notify.progress(this); LiveConfig.load(config, getCallback(1)); break; case 2: Setting.putWall(0); - Notify.progress(this); WallConfig.load(config, getCallback(2)); break; } diff --git a/app/src/main/java/com/fongmi/android/tv/App.java b/app/src/main/java/com/fongmi/android/tv/App.java index f73b62f56..3115e5351 100644 --- a/app/src/main/java/com/fongmi/android/tv/App.java +++ b/app/src/main/java/com/fongmi/android/tv/App.java @@ -72,6 +72,10 @@ public class App extends Application { return get().executor.submit(task); } + public static Future submit(Runnable task) { + return get().executor.submit(task); + } + public static void execute(Runnable runnable) { get().executor.execute(runnable); } diff --git a/app/src/main/java/com/fongmi/android/tv/api/config/VodConfig.java b/app/src/main/java/com/fongmi/android/tv/api/config/VodConfig.java index 1879218bb..4d764e932 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/config/VodConfig.java +++ b/app/src/main/java/com/fongmi/android/tv/api/config/VodConfig.java @@ -25,23 +25,22 @@ import com.google.gson.JsonObject; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.util.concurrent.Future; public class VodConfig { - private Site home; - private String wall; - private Parse parse; - private Config config; - private List doh; - private List rules; - private List sites; - private List ads; - private List flags; - private List parses; - private ExecutorService executor; - private boolean loadLive; + private volatile Site home; + private volatile String wall; + private volatile Parse parse; + private volatile Config config; + private volatile List doh; + private volatile List rules; + private volatile List sites; + private volatile List ads; + private volatile List flags; + private volatile List parses; + private volatile Future future; + private volatile boolean loadLive; private static class Loader { static volatile VodConfig INSTANCE = new VodConfig(); @@ -111,33 +110,44 @@ public class VodConfig { } public void load(Callback callback) { - if (executor != null) executor.shutdownNow(); - executor = Executors.newSingleThreadExecutor(); - executor.execute(() -> loadConfig(callback)); + if (future != null && !future.isDone()) future.cancel(true); + future = App.submit(() -> loadConfig(callback)); } private void loadConfig(Callback callback) { + loadConfig(callback, loadCache(callback)); + } + + private void loadConfig(Callback callback, boolean silent) { try { - checkJson(Json.parse(Decoder.getJson(UrlUtil.convert(config.getUrl()))).getAsJsonObject(), callback); + String json = Decoder.getJson(UrlUtil.convert(config.getUrl())); + JsonObject object = Json.parse(json).getAsJsonObject(); + checkJson(object, callback, silent); } catch (Throwable e) { - if (TextUtils.isEmpty(config.getUrl())) App.post(() -> callback.error("")); - else loadCache(callback, e); + String error = TextUtils.isEmpty(config.getUrl()) ? "" : Notify.getError(R.string.error_config_get, e); + if (!silent) App.post(() -> callback.error(error)); e.printStackTrace(); } } - private void loadCache(Callback callback, Throwable e) { - if (!TextUtils.isEmpty(config.getJson())) checkJson(Json.parse(config.getJson()).getAsJsonObject(), callback); - else App.post(() -> callback.error(Notify.getError(R.string.error_config_get, e))); + private boolean loadCache(Callback callback) { + try { + if (TextUtils.isEmpty(config.getJson())) return false; + parseConfig(Json.parse(config.getJson()).getAsJsonObject(), callback, false); + return true; + } catch (Throwable e) { + e.printStackTrace(); + return false; + } } - private void checkJson(JsonObject object, Callback callback) { + private void checkJson(JsonObject object, Callback callback, boolean silent) { if (object.has("msg")) { App.post(() -> callback.error(object.get("msg").getAsString())); } else if (object.has("urls")) { parseDepot(object, callback); } else { - parseConfig(object, callback); + parseConfig(object, callback, silent); } } @@ -150,7 +160,7 @@ public class VodConfig { loadConfig(callback); } - private void parseConfig(JsonObject object, Callback callback) { + private void parseConfig(JsonObject object, Callback callback, boolean silent) { try { initSite(object); initParse(object); @@ -160,9 +170,11 @@ public class VodConfig { config.logo(Json.safeString(object, "logo")); App.post(() -> callback.success(notice)); config.json(object.toString()).update(); + if (silent || future.isCancelled()) return; App.post(callback::success); } catch (Throwable e) { e.printStackTrace(); + if (silent) return; App.post(() -> callback.error(Notify.getError(R.string.error_config_parse, e))); } } @@ -172,16 +184,14 @@ public class VodConfig { initSite(object.getAsJsonObject("video")); return; } + List sites = new ArrayList<>(); String spider = Json.safeString(object, "spider"); BaseLoader.get().parseJar(spider, true); for (JsonElement element : Json.safeListElement(object, "sites")) { - Site site = Site.objectFrom(element); - if (sites.contains(site)) continue; - site.setApi(UrlUtil.convert(site.getApi())); - site.setExt(UrlUtil.convert(site.getExt())); - site.setJar(parseJar(site, spider)); - sites.add(site.trans().sync()); + Site site = Site.objectFrom(element, spider); + if (!sites.contains(site)) sites.add(site); } + setSites(sites); for (Site site : sites) { if (site.getKey().equals(config.getHome())) { setHome(site); @@ -189,18 +199,14 @@ public class VodConfig { } } - private void initLive(JsonObject object) { - Config temp = Config.find(config, 1).save(); - boolean sync = LiveConfig.get().needSync(config.getUrl()); - if (sync) LiveConfig.get().clear().config(temp.update()).parse(object); - } - private void initParse(JsonObject object) { + List parses = new ArrayList<>(); for (JsonElement element : Json.safeListElement(object, "parses")) { Parse parse = Parse.objectFrom(element); if (parse.getName().equals(config.getParse()) && parse.getType() > 1) setParse(parse); if (!parses.contains(parse)) parses.add(parse); } + setParses(parses); } private void initOther(JsonObject object) { @@ -217,8 +223,10 @@ public class VodConfig { setAds(Json.safeListString(object, "ads")); } - private String parseJar(Site site, String spider) { - return site.getJar().isEmpty() ? spider : site.getJar(); + private void initLive(JsonObject object) { + Config temp = Config.find(config, 1).save(); + boolean sync = LiveConfig.get().needSync(config.getUrl()); + if (sync) LiveConfig.get().clear().config(temp.update()).parse(object); } public List getDoh() { @@ -271,12 +279,20 @@ public class VodConfig { OkHttp.selector().addAll(proxy); } + public void setSites(List sites) { + this.sites = sites; + } + + public void setParses(List parses) { + this.parses = parses; + } + public List getFlags() { return flags == null ? Collections.emptyList() : flags; } private void setFlags(List flags) { - this.flags.addAll(flags); + this.flags = flags; } private void setHosts(List hosts) { diff --git a/app/src/main/java/com/fongmi/android/tv/bean/Site.java b/app/src/main/java/com/fongmi/android/tv/bean/Site.java index 0a5e9caa0..4fec12043 100644 --- a/app/src/main/java/com/fongmi/android/tv/bean/Site.java +++ b/app/src/main/java/com/fongmi/android/tv/bean/Site.java @@ -15,6 +15,7 @@ import com.fongmi.android.tv.Constant; import com.fongmi.android.tv.api.loader.BaseLoader; import com.fongmi.android.tv.db.AppDatabase; import com.fongmi.android.tv.gson.ExtAdapter; +import com.fongmi.android.tv.utils.UrlUtil; import com.github.catvod.crawler.Spider; import com.github.catvod.net.OkHttp; import com.github.catvod.utils.Json; @@ -104,9 +105,13 @@ public class Site implements Parcelable { @Ignore private boolean activated; - public static Site objectFrom(JsonElement element) { + public static Site objectFrom(JsonElement element, String spider) { try { - return App.gson().fromJson(element, Site.class); + Site site = App.gson().fromJson(element, Site.class); + if (site.getJar().isEmpty()) site.setJar(spider); + site.setApi(UrlUtil.convert(site.getApi())); + site.setExt(UrlUtil.convert(site.getExt())); + return site.trans().sync(); } catch (Exception e) { return new Site(); } diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java index 3df2ba04f..548931bdc 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java @@ -2,7 +2,6 @@ package com.fongmi.android.tv.ui.fragment; import android.app.Activity; import android.content.Intent; -import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -143,6 +142,7 @@ public class SettingFragment extends BaseFragment implements ConfigCallback, Sit if (config.getUrl().startsWith("file")) { PermissionUtil.requestFile(this, allGranted -> load(config)); } else { + Notify.progress(requireActivity()); load(config); } } @@ -150,16 +150,13 @@ public class SettingFragment extends BaseFragment implements ConfigCallback, Sit private void load(Config config) { switch (config.getType()) { case 0: - Notify.progress(requireActivity()); VodConfig.load(config, getCallback(0)); break; case 1: - Notify.progress(requireActivity()); LiveConfig.load(config, getCallback(1)); break; case 2: Setting.putWall(0); - Notify.progress(requireActivity()); WallConfig.load(config, getCallback(2)); break; }