Put ChanLoaders with no listeners in a lru cache

multisite
Floens 10 years ago
parent b83082081e
commit e38d47a47c
  1. 34
      Clover/app/src/main/java/org/floens/chan/chan/ChanLoader.java
  2. 56
      Clover/app/src/main/java/org/floens/chan/core/net/LoaderPool.java
  3. 8
      Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java
  4. 13
      Clover/app/src/main/java/org/floens/chan/ui/controller/ViewThreadController.java

@ -51,7 +51,6 @@ public class ChanLoader implements Response.ErrorListener, Response.Listener<Cha
private final RequestQueue volleyRequestQueue;
private ChanThread thread;
private boolean destroyed = false;
private boolean autoReload = false;
private ChanReaderRequest request;
@ -73,25 +72,27 @@ public class ChanLoader implements Response.ErrorListener, Response.Listener<Cha
/**
* Add a LoaderListener
*
* @param l the listener to add
* @param listener the listener to add
*/
public void addListener(ChanLoaderCallback l) {
listeners.add(l);
public void addListener(ChanLoaderCallback listener) {
listeners.add(listener);
}
/**
* Remove a LoaderListener
*
* @param l the listener to remove
* @param listener the listener to remove
* @return true if there are no more listeners, false otherwise
*/
public boolean removeListener(ChanLoaderCallback l) {
listeners.remove(l);
if (listeners.size() == 0) {
public boolean removeListener(ChanLoaderCallback listener) {
listeners.remove(listener);
if (listeners.isEmpty()) {
clearTimer();
destroyed = true;
currentTimeout = 0;
autoReload = false;
if (request != null) {
request.cancel();
request = null;
}
return true;
} else {
@ -133,6 +134,7 @@ public class ChanLoader implements Response.ErrorListener, Response.Listener<Cha
if (request != null) {
request.cancel();
// request = null;
}
if (loadable.isCatalogMode()) {
@ -158,6 +160,16 @@ public class ChanLoader implements Response.ErrorListener, Response.Listener<Cha
}
}
public void quickLoad() {
if (thread == null) {
throw new IllegalStateException("Cannot quick load without already loaded thread");
}
for (ChanLoaderCallback l : listeners) {
l.onChanLoaderData(thread);
}
}
/**
* Request more data and reset the watch timer.
*/
@ -193,8 +205,6 @@ public class ChanLoader implements Response.ErrorListener, Response.Listener<Cha
@Override
public void onResponse(ChanReaderRequest.ChanReaderResponse response) {
request = null;
if (destroyed)
return;
if (response.posts.size() == 0) {
onErrorResponse(new VolleyError("Post size is 0"));
@ -232,8 +242,6 @@ public class ChanLoader implements Response.ErrorListener, Response.Listener<Cha
@Override
public void onErrorResponse(VolleyError error) {
request = null;
if (destroyed)
return;
Logger.i(TAG, "Loading error", error);

@ -17,6 +17,8 @@
*/
package org.floens.chan.core.net;
import android.util.LruCache;
import org.floens.chan.chan.ChanLoader;
import org.floens.chan.core.model.Loadable;
@ -24,21 +26,39 @@ import java.util.HashMap;
import java.util.Map;
public class LoaderPool {
// private static final String TAG = "LoaderPool";
// private static final String TAG = "LoaderPool";
public static final int THREAD_LOADERS_CACHE_SIZE = 25;
private static LoaderPool instance = new LoaderPool();
private static Map<Loadable, ChanLoader> loaders = new HashMap<>();
public static LoaderPool getInstance() {
return instance;
}
private Map<Loadable, ChanLoader> threadLoaders = new HashMap<>();
private LruCache<Loadable, ChanLoader> threadLoadersCache = new LruCache<>(THREAD_LOADERS_CACHE_SIZE);
private LoaderPool() {
}
public ChanLoader obtain(Loadable loadable, ChanLoader.ChanLoaderCallback listener) {
ChanLoader chanLoader = loaders.get(loadable);
if (chanLoader == null) {
ChanLoader chanLoader;
if (loadable.isThreadMode()) {
chanLoader = threadLoaders.get(loadable);
if (chanLoader == null) {
chanLoader = threadLoadersCache.get(loadable);
if (chanLoader != null) {
threadLoadersCache.remove(loadable);
threadLoaders.put(loadable, chanLoader);
}
}
if (chanLoader == null) {
chanLoader = new ChanLoader(loadable);
threadLoaders.put(loadable, chanLoader);
}
} else {
chanLoader = new ChanLoader(loadable);
loaders.put(loadable, chanLoader);
}
chanLoader.addListener(listener);
@ -47,20 +67,20 @@ public class LoaderPool {
}
public void release(ChanLoader chanLoader, ChanLoader.ChanLoaderCallback listener) {
ChanLoader foundChanLoader = null;
for (Loadable l : loaders.keySet()) {
if (chanLoader.getLoadable().equals(l)) {
foundChanLoader = loaders.get(l);
break;
}
}
Loadable loadable = chanLoader.getLoadable();
if (loadable.isThreadMode()) {
ChanLoader foundChanLoader = threadLoaders.get(loadable);
if (foundChanLoader == null) {
throw new RuntimeException("The released loader does not exist");
}
if (foundChanLoader == null) {
throw new IllegalStateException("The released loader does not exist");
}
if (chanLoader.removeListener(listener)) {
loaders.remove(chanLoader.getLoadable());
if (chanLoader.removeListener(listener)) {
threadLoaders.remove(loadable);
threadLoadersCache.put(loadable, chanLoader);
}
} else {
chanLoader.removeListener(listener);
}
}
}

@ -123,6 +123,14 @@ public class ThreadPresenter implements ChanLoader.ChanLoaderCallback, PostAdapt
}
}
public void requestInitialData() {
if (chanLoader.getThread() == null) {
requestData();
} else {
chanLoader.quickLoad();
}
}
public void requestData() {
threadPresenterCallback.showLoading();
chanLoader.requestData();

@ -27,6 +27,7 @@ import org.floens.chan.chan.ChanUrls;
import org.floens.chan.core.manager.WatchManager;
import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Pin;
import org.floens.chan.core.presenter.ThreadPresenter;
import org.floens.chan.ui.cell.PostCellInterface;
import org.floens.chan.ui.layout.ThreadLayout;
import org.floens.chan.ui.toolbar.ToolbarMenu;
@ -121,15 +122,15 @@ public class ViewThreadController extends ThreadController implements ThreadLayo
}
public void loadThread(Loadable loadable) {
if (!loadable.equals(threadLayout.getPresenter().getLoadable())) {
threadLayout.getPresenter().bindLoadable(loadable);
this.loadable = threadLayout.getPresenter().getLoadable();
threadLayout.getPresenter().requestData();
ThreadPresenter presenter = threadLayout.getPresenter();
if (!loadable.equals(presenter.getLoadable())) {
presenter.bindLoadable(loadable);
this.loadable = presenter.getLoadable();
navigationItem.title = loadable.title;
navigationItem.updateTitle();
setPinIconState(threadLayout.getPresenter().isPinned());
setPinIconState(presenter.isPinned());
updateDrawerHighlighting(loadable);
presenter.requestInitialData();
}
}

Loading…
Cancel
Save