diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/base/BaseActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/base/BaseActivity.java index d13295d98..bcd09cd1d 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/base/BaseActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/base/BaseActivity.java @@ -4,12 +4,9 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import android.content.res.Configuration; import android.content.res.Resources; -import android.os.Build; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; -import android.window.OnBackInvokedCallback; -import android.window.OnBackInvokedDispatcher; import androidx.activity.OnBackPressedCallback; import androidx.annotation.NonNull; @@ -30,8 +27,6 @@ import me.jessyan.autosize.AutoSizeCompat; public abstract class BaseActivity extends AppCompatActivity { - private OnBackInvokedCallback callback; - protected abstract ViewBinding getBinding(); @Override @@ -79,16 +74,12 @@ public abstract class BaseActivity extends AppCompatActivity { } private void setBackCallback() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - getOnBackInvokedDispatcher().registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT, callback = this::onBackInvoked); - } else { - getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { - @Override - public void handleOnBackPressed() { - onBackInvoked(); - } - }); - } + getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + onBackInvoked(); + } + }); } private Resources hackResources(Resources resources) { @@ -129,6 +120,5 @@ public abstract class BaseActivity extends AppCompatActivity { protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(callback); } } diff --git a/app/src/main/java/com/fongmi/android/tv/api/config/BaseConfig.java b/app/src/main/java/com/fongmi/android/tv/api/config/BaseConfig.java index 89db5f3c2..7e6e8816e 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/config/BaseConfig.java +++ b/app/src/main/java/com/fongmi/android/tv/api/config/BaseConfig.java @@ -9,9 +9,12 @@ import com.fongmi.android.tv.event.ConfigEvent; import com.fongmi.android.tv.impl.Callback; import com.fongmi.android.tv.server.Server; import com.fongmi.android.tv.utils.Notify; +import com.github.catvod.bean.Header; +import com.github.catvod.bean.Proxy; import com.github.catvod.net.OkHttp; import java.io.InterruptedIOException; +import java.util.List; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicInteger; @@ -22,10 +25,10 @@ abstract class BaseConfig { public static final int WALL = 2; private final AtomicInteger taskId = new AtomicInteger(0); - private Future future; - protected Config config; protected boolean sync; + protected Config config; + private volatile Future future; protected abstract String getTag(); @@ -45,12 +48,17 @@ abstract class BaseConfig { return config == null ? defaultConfig() : config; } - public static String getUrl(BaseConfig instance) { - return instance.getConfig().getUrl(); + protected void setHeaders(List
headers) { + OkHttp.responseInterceptor().addAll(headers); + } + + protected void setProxy(List proxy) { + OkHttp.authenticator().addAll(proxy); + OkHttp.selector().addAll(proxy); } - public static String getDesc(BaseConfig instance) { - return instance.getConfig().getDesc(); + protected void setHosts(List hosts) { + OkHttp.dns().addAll(hosts); } public void load(Callback callback) { @@ -81,6 +89,9 @@ abstract class BaseConfig { } protected boolean isCanceled(Throwable e) { - return "Canceled".equals(e.getMessage()) || e instanceof InterruptedException || e instanceof InterruptedIOException || e.getCause() instanceof InterruptedIOException; + if ("Canceled".equals(e.getMessage())) return true; + if (e instanceof InterruptedException) return true; + if (e instanceof InterruptedIOException) return true; + return e.getCause() instanceof InterruptedIOException; } } diff --git a/app/src/main/java/com/fongmi/android/tv/api/config/LiveConfig.java b/app/src/main/java/com/fongmi/android/tv/api/config/LiveConfig.java index 04762dbea..ba02f2b82 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/config/LiveConfig.java +++ b/app/src/main/java/com/fongmi/android/tv/api/config/LiveConfig.java @@ -1,5 +1,7 @@ package com.fongmi.android.tv.api.config; +import android.text.TextUtils; + import com.fongmi.android.tv.Setting; import com.fongmi.android.tv.api.Decoder; import com.fongmi.android.tv.api.LiveParser; @@ -17,7 +19,6 @@ import com.fongmi.android.tv.impl.Callback; import com.fongmi.android.tv.utils.UrlUtil; import com.github.catvod.bean.Header; import com.github.catvod.bean.Proxy; -import com.github.catvod.net.OkHttp; import com.github.catvod.utils.Json; import com.google.gson.JsonObject; @@ -38,10 +39,6 @@ public class LiveConfig extends BaseConfig { private List rules; private List ads; - private static class Loader { - static volatile LiveConfig INSTANCE = new LiveConfig(); - } - public static LiveConfig get() { return Loader.INSTANCE; } @@ -71,8 +68,7 @@ public class LiveConfig extends BaseConfig { } public static boolean hasUrl() { - String url = getUrl(); - return url != null && !url.isEmpty(); + return !TextUtils.isEmpty(getUrl()); } public static void load(Config config, Callback callback) { @@ -147,6 +143,7 @@ public class LiveConfig extends BaseConfig { List items = Depot.arrayFrom(object.getAsJsonArray("urls").toString()); List configs = new ArrayList<>(); for (Depot item : items) configs.add(Config.find(item, LIVE)); + if (configs.isEmpty()) throw new Exception("Depot urls is empty"); load(this.config = configs.get(0)); Config.delete(config.getUrl()); } @@ -206,8 +203,9 @@ public class LiveConfig extends BaseConfig { } public int[] findByChannelNumber(String number, List items) { + int num = Integer.parseInt(number); for (int i = 0; i < items.size(); i++) { - int j = items.get(i).find(Integer.parseInt(number)); + int j = items.get(i).find(num); if (j != -1) return new int[]{i, j}; } return new int[]{-1, -1}; @@ -229,19 +227,6 @@ public class LiveConfig extends BaseConfig { this.rules = rules; } - private void setHeaders(List
headers) { - OkHttp.responseInterceptor().addAll(headers); - } - - private void setProxy(List proxy) { - OkHttp.authenticator().addAll(proxy); - OkHttp.selector().addAll(proxy); - } - - private void setHosts(List hosts) { - OkHttp.dns().addAll(hosts); - } - public List getAds() { return ads == null ? Collections.emptyList() : ads; } @@ -254,14 +239,14 @@ public class LiveConfig extends BaseConfig { return home == null ? new Live() : home; } - public Live getLive(String key) { - return getLives().stream().filter(item -> item.getName().equals(key)).findFirst().orElse(new Live()); - } - public void setHome(Live home) { setHome(getConfig(), home, true); } + public Live getLive(String key) { + return getLives().stream().filter(item -> item.getName().equals(key)).findFirst().orElse(new Live()); + } + private void setHome(Config config, Live live, boolean save) { home = live; home.setActivated(true); @@ -270,4 +255,8 @@ public class LiveConfig extends BaseConfig { getLives().forEach(item -> item.setActivated(home)); if (!save && (home.isBoot() || Setting.isBootLive())) ConfigEvent.boot(); } + + private static class Loader { + static volatile LiveConfig INSTANCE = new LiveConfig(); + } } 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 0197560f6..211b0dc10 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 @@ -17,7 +17,6 @@ import com.fongmi.android.tv.utils.UrlUtil; import com.github.catvod.bean.Doh; import com.github.catvod.bean.Header; import com.github.catvod.bean.Proxy; -import com.github.catvod.net.OkHttp; import com.github.catvod.utils.Json; import com.google.gson.JsonObject; @@ -42,10 +41,6 @@ public class VodConfig extends BaseConfig { private List flags; private List parses; - private static class Loader { - static volatile VodConfig INSTANCE = new VodConfig(); - } - public static VodConfig get() { return Loader.INSTANCE; } @@ -133,6 +128,7 @@ public class VodConfig extends BaseConfig { List items = Depot.arrayFrom(object.getAsJsonArray("urls").toString()); List configs = new ArrayList<>(); for (Depot item : items) configs.add(Config.find(item, VOD)); + if (configs.isEmpty()) throw new Exception("Depot urls is empty"); load(this.config = configs.get(0)); Config.delete(config.getUrl()); } @@ -233,15 +229,6 @@ public class VodConfig extends BaseConfig { return filter.isEmpty() ? items : filter; } - private void setHeaders(List
headers) { - OkHttp.responseInterceptor().addAll(headers); - } - - private void setProxy(List proxy) { - OkHttp.authenticator().addAll(proxy); - OkHttp.selector().addAll(proxy); - } - public List getFlags() { return flags == null ? Collections.emptyList() : flags; } @@ -250,10 +237,6 @@ public class VodConfig extends BaseConfig { this.flags = flags; } - private void setHosts(List hosts) { - OkHttp.dns().addAll(hosts); - } - public List getAds() { return ads == null ? Collections.emptyList() : ads; } @@ -266,10 +249,19 @@ public class VodConfig extends BaseConfig { return parse == null ? new Parse() : parse; } + public void setParse(Parse parse) { + setParse(getConfig(), parse, true); + } + public Site getHome() { return home == null ? new Site() : home; } + public void setHome(Site site) { + setHome(getConfig(), site, true); + RefreshEvent.home(); + } + public String getWall() { return TextUtils.isEmpty(wall) ? "" : wall; } @@ -282,10 +274,6 @@ public class VodConfig extends BaseConfig { return getSites().stream().filter(item -> item.getKey().equals(key)).findFirst().orElse(new Site()); } - public void setParse(Parse parse) { - setParse(getConfig(), parse, true); - } - private void setParse(Config config, Parse parse, boolean save) { this.parse = parse; this.parse.setActivated(true); @@ -294,11 +282,6 @@ public class VodConfig extends BaseConfig { if (save) config.save(); } - public void setHome(Site site) { - setHome(getConfig(), site, true); - RefreshEvent.home(); - } - private void setHome(Config config, Site site, boolean save) { home = site; home.setActivated(true); @@ -306,4 +289,8 @@ public class VodConfig extends BaseConfig { if (save) config.save(); getSites().forEach(item -> item.setActivated(home)); } + + private static class Loader { + static volatile VodConfig INSTANCE = new VodConfig(); + } } 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 140bbf85d..25902b651 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 @@ -25,10 +25,6 @@ public class WallConfig extends BaseConfig { private static final String TAG = WallConfig.class.getSimpleName(); - private static class Loader { - static volatile WallConfig INSTANCE = new WallConfig(); - } - public static WallConfig get() { return Loader.INSTANCE; } @@ -101,6 +97,8 @@ public class WallConfig extends BaseConfig { 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); + } finally { + bitmap.recycle(); } } @@ -123,4 +121,8 @@ public class WallConfig extends BaseConfig { return false; } } + + private static class Loader { + static volatile WallConfig INSTANCE = new WallConfig(); + } } diff --git a/app/src/main/java/com/fongmi/android/tv/api/loader/BaseLoader.java b/app/src/main/java/com/fongmi/android/tv/api/loader/BaseLoader.java index 2ece55b40..f09828344 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/loader/BaseLoader.java +++ b/app/src/main/java/com/fongmi/android/tv/api/loader/BaseLoader.java @@ -25,18 +25,26 @@ public class BaseLoader { private final PyLoader pyLoader; private final JsLoader jsLoader; - private static class Loader { - static volatile BaseLoader INSTANCE = new BaseLoader(); + private BaseLoader() { + jarLoader = new JarLoader(); + pyLoader = new PyLoader(); + jsLoader = new JsLoader(); } public static BaseLoader get() { return Loader.INSTANCE; } - private BaseLoader() { - jarLoader = new JarLoader(); - pyLoader = new PyLoader(); - jsLoader = new JsLoader(); + private static boolean isJs(String api) { + return api.contains(".js"); + } + + private static boolean isPy(String api) { + return api.contains(".py"); + } + + private static boolean isCsp(String api) { + return api.startsWith("csp_"); } public void clear() { @@ -48,12 +56,9 @@ public class BaseLoader { } public Spider getSpider(String key, String api, String ext, String jar) { - boolean js = api.contains(".js"); - boolean py = api.contains(".py"); - boolean csp = api.startsWith("csp_"); - if (py) return pyLoader.getSpider(key, api, ext); - else if (js) return jsLoader.getSpider(key, api, ext, jar); - else if (csp) return jarLoader.getSpider(key, api, ext, jar); + if (isPy(api)) return pyLoader.getSpider(key, api, ext); + else if (isJs(api)) return jsLoader.getSpider(key, api, ext, jar); + else if (isCsp(api)) return jarLoader.getSpider(key, api, ext, jar); else return new SpiderNull(); } @@ -66,12 +71,9 @@ public class BaseLoader { } public void setRecent(String key, String api, String jar) { - boolean js = api.contains(".js"); - boolean py = api.contains(".py"); - boolean csp = api.startsWith("csp_"); - if (js) jsLoader.setRecent(key); - else if (py) pyLoader.setRecent(key); - else if (csp) jarLoader.setRecent(Util.md5(jar)); + if (isJs(api)) jsLoader.setRecent(key); + else if (isPy(api)) pyLoader.setRecent(key); + else if (isCsp(api)) jarLoader.setRecent(Util.md5(jar)); } public Object[] proxy(Map params) throws Exception { @@ -83,8 +85,9 @@ public class BaseLoader { public void parseJar(String jar, boolean recent) { if (TextUtils.isEmpty(jar)) return; - jarLoader.parseJar(Util.md5(jar), jar); - if (recent) jarLoader.setRecent(Util.md5(jar)); + String key = Util.md5(jar); + jarLoader.parseJar(key, jar); + if (recent) jarLoader.setRecent(key); } public DexClassLoader dex(String jar) { @@ -98,4 +101,8 @@ public class BaseLoader { public JSONObject jsonExtMix(String flag, String key, String name, LinkedHashMap> jxs, String url) throws Throwable { return jarLoader.jsonExtMix(flag, key, name, jxs, url); } + + private static class Loader { + static volatile BaseLoader INSTANCE = new BaseLoader(); + } } diff --git a/app/src/main/java/com/fongmi/android/tv/api/loader/JarLoader.java b/app/src/main/java/com/fongmi/android/tv/api/loader/JarLoader.java index a0167d1a6..f80cb44b7 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/loader/JarLoader.java +++ b/app/src/main/java/com/fongmi/android/tv/api/loader/JarLoader.java @@ -29,7 +29,7 @@ public class JarLoader { private final ConcurrentHashMap methods; private final ConcurrentHashMap spiders; private final ConcurrentHashMap locks; - private String recent; + private volatile String recent; public JarLoader() { loaders = new ConcurrentHashMap<>(); @@ -44,6 +44,7 @@ public class JarLoader { methods.clear(); spiders.clear(); locks.clear(); + recent = null; } public void setRecent(String recent) { @@ -117,7 +118,9 @@ public class JarLoader { return spiders.computeIfAbsent(spKey, k -> { try { parseJar(jaKey, jar); - Spider spider = (Spider) loaders.get(jaKey).loadClass("com.github.catvod.spider." + api.split("csp_")[1]).newInstance(); + DexClassLoader loader = loaders.get(jaKey); + if (loader == null) return new SpiderNull(); + Spider spider = (Spider) loader.loadClass("com.github.catvod.spider." + api.split("csp_")[1]).newInstance(); spider.siteKey = key; spider.init(App.get(), ext); return spider; @@ -128,14 +131,20 @@ public class JarLoader { }); } + private DexClassLoader requireRecentLoader() { + DexClassLoader loader = loaders.get(recent); + if (loader == null) throw new IllegalStateException("No jar loaded for recent key: " + recent); + return loader; + } + public JSONObject jsonExt(String key, LinkedHashMap jxs, String url) throws Throwable { - Class clz = loaders.get(recent).loadClass("com.github.catvod.parser.Json" + key); + Class clz = requireRecentLoader().loadClass("com.github.catvod.parser.Json" + key); Method method = clz.getMethod("parse", LinkedHashMap.class, String.class); return (JSONObject) method.invoke(null, jxs, url); } public JSONObject jsonExtMix(String flag, String key, String name, LinkedHashMap> jxs, String url) throws Throwable { - Class clz = loaders.get(recent).loadClass("com.github.catvod.parser.Mix" + key); + Class clz = requireRecentLoader().loadClass("com.github.catvod.parser.Mix" + key); Method method = clz.getMethod("parse", LinkedHashMap.class, String.class, String.class, String.class); return (JSONObject) method.invoke(null, jxs, name, flag, url); } diff --git a/app/src/main/java/com/fongmi/android/tv/api/loader/JsLoader.java b/app/src/main/java/com/fongmi/android/tv/api/loader/JsLoader.java index ffb0dabcf..337ce9464 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/loader/JsLoader.java +++ b/app/src/main/java/com/fongmi/android/tv/api/loader/JsLoader.java @@ -13,7 +13,7 @@ public class JsLoader { private final ConcurrentHashMap spiders; private final Loader loader; - private String recent; + private volatile String recent; public JsLoader() { spiders = new ConcurrentHashMap<>(); @@ -24,6 +24,7 @@ public class JsLoader { spiders.values().forEach(Spider::destroy); Module.get().clear(); spiders.clear(); + recent = null; } public void setRecent(String recent) { diff --git a/app/src/main/java/com/fongmi/android/tv/api/loader/PyLoader.java b/app/src/main/java/com/fongmi/android/tv/api/loader/PyLoader.java index 956836980..115efa829 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/loader/PyLoader.java +++ b/app/src/main/java/com/fongmi/android/tv/api/loader/PyLoader.java @@ -12,7 +12,7 @@ public class PyLoader { private final ConcurrentHashMap spiders; private final Loader loader; - private String recent; + private volatile String recent; public PyLoader() { spiders = new ConcurrentHashMap<>(); @@ -22,6 +22,7 @@ public class PyLoader { public void clear() { spiders.values().forEach(Spider::destroy); spiders.clear(); + recent = null; } public void setRecent(String recent) { diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/base/BaseActivity.java b/app/src/mobile/java/com/fongmi/android/tv/ui/base/BaseActivity.java index 32ebf3414..922251ae5 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/base/BaseActivity.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/base/BaseActivity.java @@ -8,8 +8,6 @@ import android.os.Bundle; import android.view.DisplayCutout; import android.view.View; import android.view.ViewGroup; -import android.window.OnBackInvokedCallback; -import android.window.OnBackInvokedDispatcher; import androidx.activity.EdgeToEdge; import androidx.activity.OnBackPressedCallback; @@ -27,8 +25,6 @@ import org.greenrobot.eventbus.ThreadMode; public abstract class BaseActivity extends AppCompatActivity { - private OnBackInvokedCallback callback; - protected abstract ViewBinding getBinding(); @Override @@ -92,16 +88,12 @@ public abstract class BaseActivity extends AppCompatActivity { } private void setBackCallback() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - getOnBackInvokedDispatcher().registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT, callback = this::onBackInvoked); - } else { - getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { - @Override - public void handleOnBackPressed() { - onBackInvoked(); - } - }); - } + getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + onBackInvoked(); + } + }); } private void enableEdgeToEdge() { @@ -124,6 +116,5 @@ public abstract class BaseActivity extends AppCompatActivity { protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(callback); } }