Posts are now cached for threads.

Existing posts don't get finish()'ed more than once.
captchafix
Florens Douwes 12 years ago
parent 900fdb6ce4
commit 952f54338c
  1. 2
      Chan/src/org/floens/chan/activity/BaseActivity.java
  2. 108
      Chan/src/org/floens/chan/loader/ChanReaderRequest.java
  3. 19
      Chan/src/org/floens/chan/loader/Loader.java
  4. 3
      Chan/src/org/floens/chan/service/PinnedService.java

@ -7,7 +7,6 @@ import org.floens.chan.animation.SwipeDismissListViewTouchListener.DismissCallba
import org.floens.chan.manager.PinnedManager; import org.floens.chan.manager.PinnedManager;
import org.floens.chan.model.Pin; import org.floens.chan.model.Pin;
import org.floens.chan.model.Post; import org.floens.chan.model.Post;
import org.floens.chan.utils.Logger;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
@ -149,7 +148,6 @@ public abstract class BaseActivity extends Activity implements PanelSlideListene
public void onPinsChanged() { public void onPinsChanged() {
pinnedAdapter.reload(); pinnedAdapter.reload();
pinDrawerView.invalidate(); pinDrawerView.invalidate();
Logger.test("onPinsChanged");
} }
public void addPin(Pin pin) { public void addPin(Pin pin) {

@ -18,11 +18,12 @@ import com.android.volley.extra.JsonReaderRequest;
public class ChanReaderRequest extends JsonReaderRequest<List<Post>> { public class ChanReaderRequest extends JsonReaderRequest<List<Post>> {
private Loadable loadable; private Loadable loadable;
private List<Post> cached;
private ChanReaderRequest(String url, Listener<List<Post>> listener, ErrorListener errorListener) { private ChanReaderRequest(String url, Listener<List<Post>> listener, ErrorListener errorListener) {
super(url, listener, errorListener); super(url, listener, errorListener);
} }
/** /**
* Creates a ChanReaderRequest with supplied params * Creates a ChanReaderRequest with supplied params
* @param mode ThreadManager mode * @param mode ThreadManager mode
@ -32,9 +33,9 @@ public class ChanReaderRequest extends JsonReaderRequest<List<Post>> {
* @param errorListener * @param errorListener
* @return New instance of ChanReaderRequest * @return New instance of ChanReaderRequest
*/ */
public static ChanReaderRequest newInstance(Loadable loadable, Listener<List<Post>> listener, ErrorListener errorListener) { public static ChanReaderRequest newInstance(Loadable loadable, List<Post> cached, Listener<List<Post>> listener, ErrorListener errorListener) {
String url; String url;
if (loadable.isBoardMode()) { if (loadable.isBoardMode()) {
url = ChanUrls.getPageUrl(loadable.board, loadable.no); url = ChanUrls.getPageUrl(loadable.board, loadable.no);
} else if (loadable.isThreadMode()) { } else if (loadable.isThreadMode()) {
@ -44,13 +45,14 @@ public class ChanReaderRequest extends JsonReaderRequest<List<Post>> {
} else { } else {
throw new IllegalArgumentException("Unknown mode"); throw new IllegalArgumentException("Unknown mode");
} }
ChanReaderRequest request = new ChanReaderRequest(url, listener, errorListener); ChanReaderRequest request = new ChanReaderRequest(url, listener, errorListener);
request.loadable = loadable; request.loadable = loadable;
request.cached = cached;
return request; return request;
} }
@Override @Override
public Priority getPriority() { public Priority getPriority() {
return Priority.HIGH; return Priority.HIGH;
@ -59,7 +61,7 @@ public class ChanReaderRequest extends JsonReaderRequest<List<Post>> {
@Override @Override
public List<Post> readJson(JsonReader reader) { public List<Post> readJson(JsonReader reader) {
List<Post> list = new ArrayList<Post>(); List<Post> list = new ArrayList<Post>();
if (loadable.isBoardMode()) { if (loadable.isBoardMode()) {
list = loadBoard(reader); list = loadBoard(reader);
} else if (loadable.isThreadMode()) { } else if (loadable.isThreadMode()) {
@ -69,33 +71,37 @@ public class ChanReaderRequest extends JsonReaderRequest<List<Post>> {
} else { } else {
throw new IllegalArgumentException("Unknown mode"); throw new IllegalArgumentException("Unknown mode");
} }
processPosts(list); processPosts(list);
return list; return list;
} }
private void processPosts(List<Post> posts) { private void processPosts(List<Post> posts) {
for (Post post : posts) {
post.repliesFrom.clear();
}
for (Post post : posts) { for (Post post : posts) {
for (Post other : posts) { for (Post other : posts) {
if (other.repliesTo.contains(post.no)) { if (other.repliesTo.contains(post.no)) {
post.repliesFrom.add(other.no); post.repliesFrom.add(other.no);
} }
} }
post.isSavedReply = DatabaseManager.getInstance().isSavedReply(post.board, post.no); post.isSavedReply = DatabaseManager.getInstance().isSavedReply(post.board, post.no);
} }
} }
private List<Post> loadThread(JsonReader reader) { private List<Post> loadThread(JsonReader reader) {
ArrayList<Post> list = new ArrayList<Post>(); ArrayList<Post> list = new ArrayList<Post>();
try { try {
reader.beginObject(); reader.beginObject();
// Page object // Page object
while (reader.hasNext()) { while (reader.hasNext()) {
if (reader.nextName().equals("posts")) { if (reader.nextName().equals("posts")) {
reader.beginArray(); reader.beginArray();
// Thread array // Thread array
while (reader.hasNext()) { while (reader.hasNext()) {
// Thread object // Thread object
@ -117,43 +123,43 @@ public class ChanReaderRequest extends JsonReaderRequest<List<Post>> {
e.printStackTrace(); e.printStackTrace();
setError(new ParseError(e)); setError(new ParseError(e));
} }
return list; return list;
} }
private List<Post> loadBoard(JsonReader reader) { private List<Post> loadBoard(JsonReader reader) {
ArrayList<Post> list = new ArrayList<Post>(); ArrayList<Post> list = new ArrayList<Post>();
try { try {
reader.beginObject(); // Threads array reader.beginObject(); // Threads array
if (reader.nextName().equals("threads")) { if (reader.nextName().equals("threads")) {
reader.beginArray(); reader.beginArray();
while (reader.hasNext()) { while (reader.hasNext()) {
reader.beginObject(); // Thread object reader.beginObject(); // Thread object
if (reader.nextName().equals("posts")) { if (reader.nextName().equals("posts")) {
reader.beginArray(); reader.beginArray();
list.add(readPostObject(reader)); list.add(readPostObject(reader));
// Only consume one post // Only consume one post
while (reader.hasNext()) reader.skipValue(); while (reader.hasNext()) reader.skipValue();
reader.endArray(); reader.endArray();
} else { } else {
reader.skipValue(); reader.skipValue();
} }
reader.endObject(); reader.endObject();
} }
reader.endArray(); reader.endArray();
} else { } else {
reader.skipValue(); reader.skipValue();
} }
reader.endObject(); reader.endObject();
} catch(IOException e) { } catch(IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -165,36 +171,36 @@ public class ChanReaderRequest extends JsonReaderRequest<List<Post>> {
e.printStackTrace(); e.printStackTrace();
setError(new ParseError(e)); setError(new ParseError(e));
} }
return list; return list;
} }
private List<Post> loadCatalog(JsonReader reader) { private List<Post> loadCatalog(JsonReader reader) {
ArrayList<Post> list = new ArrayList<Post>(); ArrayList<Post> list = new ArrayList<Post>();
try { try {
reader.beginArray(); // Array of pages reader.beginArray(); // Array of pages
while (reader.hasNext()) { while (reader.hasNext()) {
reader.beginObject(); // Page object reader.beginObject(); // Page object
while (reader.hasNext()) { while (reader.hasNext()) {
if (reader.nextName().equals("threads")) { if (reader.nextName().equals("threads")) {
reader.beginArray(); // Threads array reader.beginArray(); // Threads array
while (reader.hasNext()) { while (reader.hasNext()) {
list.add(readPostObject(reader)); list.add(readPostObject(reader));
} }
reader.endArray(); reader.endArray();
} else { } else {
reader.skipValue(); reader.skipValue();
} }
} }
reader.endObject(); reader.endObject();
} }
reader.endArray(); reader.endArray();
} catch(IOException e) { } catch(IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -206,18 +212,18 @@ public class ChanReaderRequest extends JsonReaderRequest<List<Post>> {
e.printStackTrace(); e.printStackTrace();
setError(new ParseError(e)); setError(new ParseError(e));
} }
return list; return list;
} }
private Post readPostObject(JsonReader reader) throws IllegalStateException, NumberFormatException, IOException { private Post readPostObject(JsonReader reader) throws IllegalStateException, NumberFormatException, IOException {
Post post = new Post(); Post post = new Post();
post.board = loadable.board; post.board = loadable.board;
reader.beginObject(); reader.beginObject();
while(reader.hasNext()) { while(reader.hasNext()) {
String key = reader.nextName(); String key = reader.nextName();
if (key.equals("no")) { if (key.equals("no")) {
// Post number // Post number
post.no = reader.nextInt(); post.no = reader.nextInt();
@ -272,12 +278,24 @@ public class ChanReaderRequest extends JsonReaderRequest<List<Post>> {
} }
} }
reader.endObject(); reader.endObject();
if (!post.finish(loadable)) { Post cachedResult = null;
throw new IOException("Incorrect data about post received."); for (Post possibleCached : cached) {
if (possibleCached.no == post.no) {
cachedResult = possibleCached;
break;
}
}
if (cachedResult != null) {
return cachedResult;
} else {
if (!post.finish(loadable)) {
throw new IOException("Incorrect data about post received.");
}
return post;
} }
return post;
} }
} }

@ -25,6 +25,7 @@ public class Loader {
private final List<LoaderListener> listeners = new ArrayList<LoaderListener>(); private final List<LoaderListener> listeners = new ArrayList<LoaderListener>();
private final Loadable loadable; private final Loadable loadable;
private final SparseArray<Post> postsById = new SparseArray<Post>(); private final SparseArray<Post> postsById = new SparseArray<Post>();
private final List<Post> cachedPosts = new ArrayList<Post>();
private boolean destroyed = false; private boolean destroyed = false;
private ChanReaderRequest request; private ChanReaderRequest request;
@ -75,7 +76,7 @@ public class Loader {
currentTimeout = 0; currentTimeout = 0;
request = getData(loadable); request = getData();
} }
public void requestNextData() { public void requestNextData() {
@ -86,7 +87,7 @@ public class Loader {
request.cancel(); request.cancel();
} }
request = getData(loadable); request = getData();
} else if (loadable.isThreadMode()) { } else if (loadable.isThreadMode()) {
if (request != null) { if (request != null) {
return; return;
@ -94,7 +95,7 @@ public class Loader {
clearTimer(); clearTimer();
request = getData(loadable); request = getData();
} }
} }
@ -175,10 +176,10 @@ public class Loader {
requestNextData(); requestNextData();
} }
private ChanReaderRequest getData(Loadable loadable) { private ChanReaderRequest getData() {
Logger.i(TAG, "Requested " + loadable.board + ", " + loadable.no); Logger.i(TAG, "Requested " + loadable.board + ", " + loadable.no);
ChanReaderRequest request = ChanReaderRequest.newInstance(loadable, new Response.Listener<List<Post>>() { ChanReaderRequest request = ChanReaderRequest.newInstance(loadable, cachedPosts, new Response.Listener<List<Post>>() {
@Override @Override
public void onResponse(List<Post> list) { public void onResponse(List<Post> list) {
Loader.this.request = null; Loader.this.request = null;
@ -200,6 +201,12 @@ public class Loader {
private void onData(List<Post> result) { private void onData(List<Post> result) {
if (destroyed) return; if (destroyed) return;
cachedPosts.clear();
if (loadable.isThreadMode()) {
cachedPosts.addAll(result);
}
postsById.clear(); postsById.clear();
for (Post post : result) { for (Post post : result) {
postsById.append(post.no, post); postsById.append(post.no, post);
@ -218,6 +225,8 @@ public class Loader {
private void onError(VolleyError error) { private void onError(VolleyError error) {
if (destroyed) return; if (destroyed) return;
cachedPosts.clear();
Logger.e(TAG, "Error loading " + error.getMessage(), error); Logger.e(TAG, "Error loading " + error.getMessage(), error);
// 404 with more pages already loaded means endofline // 404 with more pages already loaded means endofline

@ -5,7 +5,6 @@ import java.util.List;
import org.floens.chan.manager.PinnedManager; import org.floens.chan.manager.PinnedManager;
import org.floens.chan.model.Pin; import org.floens.chan.model.Pin;
import org.floens.chan.utils.ChanPreferences; import org.floens.chan.utils.ChanPreferences;
import org.floens.chan.utils.Logger;
import org.floens.chan.watch.WatchNotifier; import org.floens.chan.watch.WatchNotifier;
import android.app.Service; import android.app.Service;
@ -28,12 +27,10 @@ public class PinnedService extends Service {
private final WatchNotifier watchNotifier; private final WatchNotifier watchNotifier;
public static void onActivityStart() { public static void onActivityStart() {
Logger.test("onActivityStart");
activityInForeground = true; activityInForeground = true;
} }
public static void onActivityStop() { public static void onActivityStop() {
Logger.test("onActivityStop");
activityInForeground = false; activityInForeground = false;
} }

Loading…
Cancel
Save