From 622bda365113c1e85a7ab0e7daf06f3cb859d8e3 Mon Sep 17 00:00:00 2001 From: jhengazuki Date: Fri, 31 Oct 2025 03:35:54 +0800 Subject: [PATCH] Optimize searchContent --- .../tv/ui/activity/CollectActivity.java | 32 ++------ .../android/tv/ui/activity/VideoActivity.java | 24 +----- .../tv/ui/fragment/CollectFragment.java | 2 +- .../android/tv/model/SearchCallable.java | 52 +++++++++++++ .../android/tv/model/SiteViewModel.java | 75 +++++++------------ .../android/tv/ui/activity/VideoActivity.java | 24 +----- .../tv/ui/fragment/CollectFragment.java | 19 +---- 7 files changed, 87 insertions(+), 141 deletions(-) create mode 100644 app/src/main/java/com/fongmi/android/tv/model/SearchCallable.java diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CollectActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CollectActivity.java index c767f8837..daf35a8c7 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CollectActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CollectActivity.java @@ -3,6 +3,7 @@ package com.fongmi.android.tv.ui.activity; import android.app.Activity; import android.content.Intent; import android.os.Parcelable; +import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -35,14 +36,11 @@ import com.google.gson.reflect.TypeToken; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; public class CollectActivity extends BaseActivity { private ActivityCollectBinding mBinding; private ArrayObjectAdapter mAdapter; - private ExecutorService mExecutor; private SiteViewModel mViewModel; private View mOldView; @@ -128,34 +126,20 @@ public class CollectActivity extends BaseActivity { List sites = getSites(); if (sites.isEmpty()) return; mAdapter.add(Collect.all()); - if (mExecutor != null) stop(); - mExecutor = Executors.newCachedThreadPool(); mBinding.pager.getAdapter().notifyDataSetChanged(); mBinding.result.setText(getString(R.string.collect_result, getKeyword())); - for (Site site : sites) mExecutor.execute(() -> search(site)); - } - - private void search(Site site) { - try { - mViewModel.searchContent(site, getKeyword(), false); - } catch (Throwable ignored) { - } + mViewModel.searchContent(sites, getKeyword(), false); } private void saveKeyword() { - List items = Setting.getKeyword().isEmpty() ? new ArrayList<>() : App.gson().fromJson(Setting.getKeyword(), new TypeToken>() {}.getType()); + List items = Setting.getKeyword().isEmpty() ? new ArrayList<>() : App.gson().fromJson(Setting.getKeyword(), new TypeToken>() { + }.getType()); items.remove(getKeyword()); items.add(0, getKeyword()); if (items.size() > 8) items.remove(8); Setting.putKeyword(App.gson().toJson(items)); } - private void stop() { - if (mExecutor == null) return; - mExecutor.shutdownNow(); - mExecutor = null; - } - private void onChildSelected(@Nullable RecyclerView.ViewHolder child) { if (mOldView != null) mOldView.setActivated(false); if (child == null) return; @@ -171,16 +155,10 @@ public class CollectActivity extends BaseActivity { } }; - @Override - protected void onBackInvoked() { - super.onBackInvoked(); - stop(); - } - @Override protected void onDestroy() { super.onDestroy(); - stop(); + Log.e("DDD", "onDestroy"); } class PageAdapter extends FragmentStatePagerAdapter { diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java index 1431db679..adbabf659 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java @@ -95,8 +95,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.UUID; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.regex.Matcher; public class VideoActivity extends BaseActivity implements CustomKeyDownVod.Listener, TrackDialog.Listener, ArrayPresenter.OnClickListener, Clock.Callback { @@ -117,7 +115,6 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List private FlagPresenter mFlagPresenter; private PartPresenter mPartPresenter; private CustomKeyDownVod mKeyDown; - private ExecutorService mExecutor; private SiteViewModel mViewModel; private List mBroken; private History mHistory; @@ -261,7 +258,6 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List String id = Objects.toString(intent.getStringExtra("id"), ""); if (TextUtils.isEmpty(id) || id.equals(getId())) return; getIntent().putExtras(intent); - stopSearch(); checkId(); } @@ -441,7 +437,6 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List private void showEmpty() { mBinding.progressLayout.showEmpty(); - stopSearch(); } private void setDetail(Vod item) { @@ -1168,7 +1163,6 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List } private void initSearch(String keyword, boolean auto) { - stopSearch(); setAutoMode(auto); setInitAuto(auto); startSearch(keyword); @@ -1183,22 +1177,8 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List private void startSearch(String keyword) { mQuickAdapter.clear(); List sites = new ArrayList<>(); - mExecutor = Executors.newCachedThreadPool(); for (Site site : VodConfig.get().getSites()) if (isPass(site)) sites.add(site); - for (Site site : sites) mExecutor.execute(() -> search(site, keyword)); - } - - private void stopSearch() { - if (mExecutor == null) return; - mExecutor.shutdownNow(); - mExecutor = null; - } - - private void search(Site site, String keyword) { - try { - mViewModel.searchContent(site, keyword, true); - } catch (Throwable ignored) { - } + mViewModel.searchContent(sites, keyword, true); } private void setSearch(Result result) { @@ -1428,14 +1408,12 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List } else if (isFullscreen()) { exitFullscreen(); } else { - stopSearch(); super.onBackInvoked(); } } @Override protected void onDestroy() { - stopSearch(); saveHistory(); mClock.release(); mPlayers.release(); diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/fragment/CollectFragment.java b/app/src/leanback/java/com/fongmi/android/tv/ui/fragment/CollectFragment.java index 1dde7a741..04a2675a2 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/fragment/CollectFragment.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/fragment/CollectFragment.java @@ -130,7 +130,7 @@ public class CollectFragment extends BaseFragment implements CustomScroller.Call @Override public void onLoadMore(String page) { if (mCollect == null || "all".equals(mCollect.getSite().getKey())) return; - mViewModel.searchContent(mCollect.getSite(), getKeyword(), page); + mViewModel.searchContent(mCollect.getSite(), getKeyword(), false, page); mScroller.setLoading(true); } diff --git a/app/src/main/java/com/fongmi/android/tv/model/SearchCallable.java b/app/src/main/java/com/fongmi/android/tv/model/SearchCallable.java new file mode 100644 index 000000000..064a2c8f4 --- /dev/null +++ b/app/src/main/java/com/fongmi/android/tv/model/SearchCallable.java @@ -0,0 +1,52 @@ +package com.fongmi.android.tv.model; + +import androidx.collection.ArrayMap; + +import com.fongmi.android.tv.bean.Result; +import com.fongmi.android.tv.bean.Site; +import com.fongmi.android.tv.bean.Vod; +import com.github.catvod.crawler.SpiderDebug; +import com.github.catvod.utils.Trans; + +import java.util.concurrent.Callable; + +public class SearchCallable implements Callable { + + private final SiteViewModel model; + private final String keyword; + private final boolean quick; + private final String page; + private final Site site; + + public SearchCallable(SiteViewModel model, Site site, String keyword, boolean quick, String page) { + this.keyword = Trans.t2s(keyword); + this.model = model; + this.quick = quick; + this.page = page; + this.site = site; + } + + @Override + public Result call() throws Exception { + if (quick && !site.isQuickSearch()) return Result.empty(); + boolean hasPage = !page.equals("1"); + if (site.getType() == 3) { + String searchContent = hasPage ? site.spider().searchContent(keyword, quick, page) : site.spider().searchContent(keyword, quick); + SpiderDebug.log(site.getName() + "," + searchContent); + Result result = Result.fromJson(searchContent); + for (Vod vod : result.getList()) vod.setSite(site); + return result; + } else { + ArrayMap params = new ArrayMap<>(); + params.put("wd", keyword); + params.put("quick", String.valueOf(quick)); + params.put("extend", ""); + if (hasPage) params.put("pg", page); + String searchContent = model.call(site, params); + SpiderDebug.log(site.getName() + "," + searchContent); + Result result = model.fetchPic(site, Result.fromType(site.getType(), searchContent)); + for (Vod vod : result.getList()) vod.setSite(site); + return result; + } + } +} diff --git a/app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java b/app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java index dd4cfe12a..df75ae9db 100644 --- a/app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java +++ b/app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java @@ -1,6 +1,7 @@ package com.fongmi.android.tv.model; import android.text.TextUtils; +import android.util.Log; import androidx.collection.ArrayMap; import androidx.lifecycle.MutableLiveData; @@ -24,13 +25,13 @@ import com.github.catvod.crawler.Spider; import com.github.catvod.crawler.SpiderDebug; import com.github.catvod.net.OkHttp; import com.github.catvod.utils.Prefers; -import com.github.catvod.utils.Trans; import com.github.catvod.utils.Util; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -42,6 +43,7 @@ import okhttp3.Response; public class SiteViewModel extends ViewModel { + private final List> searchFutures; private final ExecutorService executor; private Future future; @@ -57,6 +59,7 @@ public class SiteViewModel extends ViewModel { player = new MutableLiveData<>(); search = new MutableLiveData<>(); action = new MutableLiveData<>(); + searchFutures = new ArrayList<>(); executor = Executors.newSingleThreadExecutor(); } @@ -206,6 +209,23 @@ public class SiteViewModel extends ViewModel { }); } + public void searchContent(List sites, String keyword, boolean quick) { + for (Future f : searchFutures) f.cancel(true); + for (Site site : sites) searchContent(site, keyword, quick, "1"); + } + + public void searchContent(Site site, String keyword, boolean quick, String page) { + Callable callable = new SearchCallable(this, site, keyword, quick, page); + if (!page.equals("1")) execute(result, callable); + else searchFutures.add(App.submit(() -> { + try { + Result taskResult = callable.call(); + if (!taskResult.getList().isEmpty()) search.postValue(taskResult); + } catch (Throwable ignored) { + } + })); + } + public void action(String key, String action) { execute(this.action, () -> { Site site = VodConfig.get().getSite(key); @@ -215,48 +235,7 @@ public class SiteViewModel extends ViewModel { }); } - public void searchContent(Site site, String keyword, boolean quick) throws Throwable { - if (site.getType() == 3) { - if (quick && !site.isQuickSearch()) return; - String searchContent = site.spider().searchContent(Trans.t2s(keyword), quick); - SpiderDebug.log(site.getName() + "," + searchContent); - post(site, Result.fromJson(searchContent)); - } else { - if (quick && !site.isQuickSearch()) return; - ArrayMap params = new ArrayMap<>(); - params.put("wd", Trans.t2s(keyword)); - params.put("quick", String.valueOf(quick)); - params.put("extend", ""); - String searchContent = call(site, params); - SpiderDebug.log(site.getName() + "," + searchContent); - post(site, fetchPic(site, Result.fromType(site.getType(), searchContent))); - } - } - - public void searchContent(Site site, String keyword, String page) { - execute(result, () -> { - if (site.getType() == 3) { - String searchContent = site.spider().searchContent(Trans.t2s(keyword), false, page); - SpiderDebug.log(site.getName() + "," + searchContent); - Result result = Result.fromJson(searchContent); - for (Vod vod : result.getList()) vod.setSite(site); - return result; - } else { - ArrayMap params = new ArrayMap<>(); - params.put("wd", Trans.t2s(keyword)); - params.put("quick", "false"); - params.put("extend", ""); - params.put("pg", page); - String searchContent = call(site, params); - SpiderDebug.log(site.getName() + "," + searchContent); - Result result = fetchPic(site, Result.fromType(site.getType(), searchContent)); - for (Vod vod : result.getList()) vod.setSite(site); - return result; - } - }); - } - - private String call(Site site, ArrayMap params) throws IOException { + public String call(Site site, ArrayMap params) throws IOException { if (!site.getExt().isEmpty()) params.put("extend", site.getExt()); Call get = OkHttp.newCall(site.getApi(), site.getHeaders(), params); Call post = OkHttp.newCall(site.getApi(), site.getHeaders(), OkHttp.toBody(params)); @@ -265,7 +244,7 @@ public class SiteViewModel extends ViewModel { } } - private Result fetchPic(Site site, Result result) throws Exception { + public Result fetchPic(Site site, Result result) throws Exception { if (site.getType() > 2 || result.getList().isEmpty() || !result.getList().get(0).getVodPic().isEmpty()) return result; ArrayList ids = new ArrayList<>(); boolean empty = site.getCategories().isEmpty(); @@ -280,12 +259,6 @@ public class SiteViewModel extends ViewModel { } } - private void post(Site site, Result result) { - if (result.getList().isEmpty()) return; - for (Vod vod : result.getList()) vod.setSite(site); - search.postValue(result); - } - private void execute(MutableLiveData result, Callable callable) { if (future != null && !future.isDone()) future.cancel(true); future = App.submit(callable); @@ -308,7 +281,9 @@ public class SiteViewModel extends ViewModel { @Override protected void onCleared() { super.onCleared(); + Log.e("DDD", "onCleared"); if (future != null) future.cancel(true); if (executor != null) executor.shutdownNow(); + for (Future f : searchFutures) f.cancel(true); } } diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java index 2fde0b060..85b3809b4 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java @@ -110,8 +110,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.UUID; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.regex.Matcher; public class VideoActivity extends BaseActivity implements Clock.Callback, CustomKeyDown.Listener, TrackDialog.Listener, ControlDialog.Listener, FlagAdapter.OnClickListener, EpisodeAdapter.OnClickListener, QualityAdapter.OnClickListener, QuickAdapter.OnClickListener, ParseAdapter.OnClickListener, CastDialog.Listener, InfoDialog.Listener { @@ -126,7 +124,6 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo private ControlDialog mControlDialog; private QuickAdapter mQuickAdapter; private ParseAdapter mParseAdapter; - private ExecutorService mExecutor; private SiteViewModel mViewModel; private FlagAdapter mFlagAdapter; private ValueAnimator mAnimator; @@ -269,7 +266,6 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo if (TextUtils.isEmpty(id) || id.equals(getId())) return; mBinding.swipeLayout.setRefreshing(true); getIntent().putExtras(intent); - stopSearch(); setOrient(); checkId(); } @@ -477,7 +473,6 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo showError(getString(R.string.error_detail)); mBinding.swipeLayout.setEnabled(true); mBinding.progressLayout.showEmpty(); - stopSearch(); } private void setDetail(Vod item) { @@ -1309,7 +1304,6 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo } private void initSearch(String keyword, boolean auto) { - stopSearch(); setAutoMode(auto); setInitAuto(auto); startSearch(keyword); @@ -1323,22 +1317,8 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo private void startSearch(String keyword) { mQuickAdapter.clear(); List sites = new ArrayList<>(); - mExecutor = Executors.newCachedThreadPool(); for (Site item : VodConfig.get().getSites()) if (isPass(item)) sites.add(item); - for (Site site : sites) mExecutor.execute(() -> search(site, keyword)); - } - - private void stopSearch() { - if (mExecutor == null) return; - mExecutor.shutdownNow(); - mExecutor = null; - } - - private void search(Site site, String keyword) { - try { - mViewModel.searchContent(site, keyword, true); - } catch (Throwable ignored) { - } + mViewModel.searchContent(sites, keyword, true); } private void setSearch(Result result) { @@ -1673,14 +1653,12 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo } else if (isFullscreen() && !isLock()) { exitFullscreen(); } else if (!isLock()) { - stopSearch(); super.onBackInvoked(); } } @Override protected void onDestroy() { - stopSearch(); saveHistory(); mClock.release(); mPlayers.release(); diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/CollectFragment.java b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/CollectFragment.java index cb3118005..e7d998b17 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/CollectFragment.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/CollectFragment.java @@ -33,15 +33,12 @@ import com.fongmi.android.tv.utils.ResUtil; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; public class CollectFragment extends BaseFragment implements MenuProvider, CollectAdapter.OnClickListener, SearchAdapter.OnClickListener, CustomScroller.Callback { private FragmentCollectBinding mBinding; private CollectAdapter mCollectAdapter; private SearchAdapter mSearchAdapter; - private ExecutorService mExecutor; private CustomScroller mScroller; private SiteViewModel mViewModel; private List sites; @@ -118,18 +115,7 @@ public class CollectFragment extends BaseFragment implements MenuProvider, Colle } private void search() { - if (sites.isEmpty()) return; - mExecutor = Executors.newCachedThreadPool(); - mCollectAdapter.setItems(List.of(Collect.all()), () -> { - for (Site site : sites) mExecutor.execute(() -> search(site, getKeyword())); - }); - } - - private void search(Site site, String keyword) { - try { - mViewModel.searchContent(site, keyword, false); - } catch (Throwable ignored) { - } + if (!sites.isEmpty()) mCollectAdapter.setItems(List.of(Collect.all()), () -> mViewModel.searchContent(sites, getKeyword(), false)); } private int getCount() { @@ -170,7 +156,7 @@ public class CollectFragment extends BaseFragment implements MenuProvider, Colle public void onLoadMore(String page) { Collect activated = mCollectAdapter.getActivated(); if ("all".equals(activated.getSite().getKey())) return; - mViewModel.searchContent(activated.getSite(), getKeyword(), page); + mViewModel.searchContent(activated.getSite(), getKeyword(), false, page); activated.setPage(Integer.parseInt(page)); mScroller.setLoading(true); } @@ -195,6 +181,5 @@ public class CollectFragment extends BaseFragment implements MenuProvider, Colle public void onDestroyView() { super.onDestroyView(); requireActivity().removeMenuProvider(this); - if (mExecutor != null) mExecutor.shutdownNow(); } }