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 58a88339c..2f75d38e6 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 @@ -27,18 +27,21 @@ import com.fongmi.android.tv.databinding.ActivityCollectBinding; import com.fongmi.android.tv.model.SiteViewModel; import com.fongmi.android.tv.ui.fragment.CollectFragment; import com.fongmi.android.tv.ui.presenter.CollectPresenter; +import com.fongmi.android.tv.utils.PausableThreadPoolExecutor; 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; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; public class CollectActivity extends BaseActivity { private ActivityCollectBinding mBinding; private ArrayObjectAdapter mAdapter; - private ExecutorService mExecutor; + private PausableThreadPoolExecutor mExecutor; private SiteViewModel mViewModel; private PageAdapter mPageAdapter; private List mSites; @@ -121,7 +124,9 @@ public class CollectActivity extends BaseActivity { private void search() { mAdapter.add(Collect.all()); mPageAdapter.notifyDataSetChanged(); - mExecutor = Executors.newFixedThreadPool(Constant.THREAD_POOL); + int core = Runtime.getRuntime().availableProcessors(); + int corePoolSize = Math.max(Constant.THREAD_POOL, core); + mExecutor = new PausableThreadPoolExecutor(corePoolSize, corePoolSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); mBinding.result.setText(getString(R.string.collect_result, getKeyword())); for (Site site : mSites) mExecutor.execute(() -> search(site)); } @@ -157,7 +162,20 @@ public class CollectActivity extends BaseActivity { super.onBackPressed(); if (mExecutor == null) return; mExecutor.shutdownNow(); - mExecutor = null; + } + + @Override + protected void onPause() { + super.onPause(); + if (mExecutor == null) return; + mExecutor.pause(); + } + + @Override + protected void onResume() { + super.onResume(); + if (mExecutor == null) return; + mExecutor.resume(); } class PageAdapter extends FragmentStatePagerAdapter { diff --git a/app/src/main/java/com/fongmi/android/tv/utils/PausableThreadPoolExecutor.java b/app/src/main/java/com/fongmi/android/tv/utils/PausableThreadPoolExecutor.java new file mode 100644 index 000000000..f048f95bb --- /dev/null +++ b/app/src/main/java/com/fongmi/android/tv/utils/PausableThreadPoolExecutor.java @@ -0,0 +1,49 @@ +package com.fongmi.android.tv.utils; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +public class PausableThreadPoolExecutor extends ThreadPoolExecutor { + private boolean isPaused; + private ReentrantLock pauseLock = new ReentrantLock(); + private Condition unpaused = pauseLock.newCondition(); + + public PausableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) { + super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); + } + + protected void beforeExecute(Thread t, Runnable r) { + super.beforeExecute(t, r); + pauseLock.lock(); + try { + while (isPaused) unpaused.await(); + } catch (InterruptedException ie) { + t.interrupt(); + } finally { + pauseLock.unlock(); + } + } + + public void pause() { + pauseLock.lock(); + try { + isPaused = true; + } finally { + pauseLock.unlock(); + } + } + + public void resume() { + pauseLock.lock(); + try { + isPaused = false; + unpaused.signalAll(); + } finally { + pauseLock.unlock(); + } + } +} +