1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-05 10:49:24 +02:00

refactoring: user data in NetworkTree instead of map in NetworkView

This commit is contained in:
Nikolay Pultsin 2011-04-30 14:49:00 +01:00
parent 2c3d3c11f8
commit c0437dafef
11 changed files with 101 additions and 90 deletions

View file

@ -19,17 +19,47 @@
package org.geometerplus.android.fbreader.network; package org.geometerplus.android.fbreader.network;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder; import android.os.IBinder;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.app.Service;
import android.content.Intent;
import org.geometerplus.fbreader.network.NetworkTree; import org.geometerplus.fbreader.network.NetworkTree;
public class ItemsLoadingService extends Service { public class ItemsLoadingService extends Service {
private static final String KEY = "ItemsLoadingRunnable";
public static final String ITEMS_LOADING_RUNNABLE_KEY = "org.geometerplus.android.fbreader.network.ItemsLoadingRunnable"; static void start(Context context, NetworkTree tree, ItemsLoadingRunnable runnable) {
boolean doDownload = false;
synchronized (tree) {
if (tree.getUserData(KEY) == null) {
tree.setUserData(KEY, runnable);
doDownload = true;
}
}
if (doDownload) {
context.startService(
new Intent(context.getApplicationContext(), ItemsLoadingService.class)
.putExtra(Util.TREE_KEY_KEY, tree.getUniqueKey())
);
}
}
static ItemsLoadingRunnable getRunnable(NetworkTree tree) {
return (ItemsLoadingRunnable)tree.getUserData(KEY);
}
private static void removeRunnable(NetworkTree tree) {
synchronized (tree) {
ItemsLoadingRunnable runnable = (ItemsLoadingRunnable)tree.getUserData(KEY);
if (runnable != null) {
tree.setUserData(KEY, null);
runnable.runFinishHandler();
}
}
}
private volatile int myServiceCounter; private volatile int myServiceCounter;
@ -54,18 +84,19 @@ public class ItemsLoadingService extends Service {
super.onStart(intent, startId); super.onStart(intent, startId);
doStart(); doStart();
final NetworkTree.Key key = (NetworkTree.Key)intent.getSerializableExtra(ITEMS_LOADING_RUNNABLE_KEY); final NetworkTree tree = Util.getTreeFromIntent(intent);
if (key == null) { if (tree == null) {
doStop(); doStop();
return; return;
} }
intent.removeExtra(ITEMS_LOADING_RUNNABLE_KEY); intent.removeExtra(Util.TREE_KEY_KEY);
if (!NetworkView.Instance().isInitialized()) { if (!NetworkView.Instance().isInitialized()) {
doStop(); doStop();
return; return;
} }
final ItemsLoadingRunnable runnable = NetworkView.Instance().getItemsLoadingRunnable(key);
final ItemsLoadingRunnable runnable = getRunnable(tree);
if (runnable == null) { if (runnable == null) {
doStop(); doStop();
return; return;
@ -74,8 +105,8 @@ public class ItemsLoadingService extends Service {
final Handler finishHandler = new Handler() { final Handler finishHandler = new Handler() {
public void handleMessage(Message message) { public void handleMessage(Message message) {
doStop(); doStop();
removeRunnable(tree);
if (NetworkView.Instance().isInitialized()) { if (NetworkView.Instance().isInitialized()) {
NetworkView.Instance().removeItemsLoadingRunnable(key);
NetworkView.Instance().fireModelChangedAsync(); NetworkView.Instance().fireModelChangedAsync();
} }
} }

View file

@ -176,7 +176,7 @@ class NetworkCatalogActions extends NetworkTreeActions {
prepareOptionsItem(menu, RELOAD_ITEM_ID, prepareOptionsItem(menu, RELOAD_ITEM_ID,
urlItem != null && urlItem != null &&
urlItem.getUrl(UrlInfo.Type.Catalog) != null && urlItem.getUrl(UrlInfo.Type.Catalog) != null &&
!NetworkView.Instance().containsItemsLoadingRunnable(tree.getUniqueKey()) ItemsLoadingService.getRunnable(tree) == null
); );
boolean signIn = false; boolean signIn = false;
@ -438,9 +438,9 @@ class NetworkCatalogActions extends NetworkTreeActions {
* 3) Remove unused messages (say, by timeout) * 3) Remove unused messages (say, by timeout)
*/ */
final ExpandCatalogHandler handler = new ExpandCatalogHandler(tree, key); final ExpandCatalogHandler handler = new ExpandCatalogHandler(tree, key);
NetworkView.Instance().startItemsLoading( ItemsLoadingService.start(
activity, activity,
key, tree,
new ExpandCatalogRunnable(handler, tree, true, resumeNotLoad) new ExpandCatalogRunnable(handler, tree, true, resumeNotLoad)
); );
processExtraData(activity, tree.Item.extraData(), new Runnable() { processExtraData(activity, tree.Item.extraData(), new Runnable() {
@ -453,17 +453,16 @@ class NetworkCatalogActions extends NetworkTreeActions {
} }
public void doReloadCatalog(NetworkBaseActivity activity, final NetworkCatalogTree tree) { public void doReloadCatalog(NetworkBaseActivity activity, final NetworkCatalogTree tree) {
final NetworkTree.Key key = tree.getUniqueKey(); if (ItemsLoadingService.getRunnable(tree) != null) {
if (NetworkView.Instance().containsItemsLoadingRunnable(key)) {
return; return;
} }
tree.ChildrenItems.clear(); tree.ChildrenItems.clear();
tree.clear(); tree.clear();
NetworkView.Instance().fireModelChangedAsync(); NetworkView.Instance().fireModelChangedAsync();
final ExpandCatalogHandler handler = new ExpandCatalogHandler(tree, key); final ExpandCatalogHandler handler = new ExpandCatalogHandler(tree, tree.getUniqueKey());
NetworkView.Instance().startItemsLoading( ItemsLoadingService.start(
activity, activity,
key, tree,
new ExpandCatalogRunnable(handler, tree, false, false) new ExpandCatalogRunnable(handler, tree, false, false)
); );
} }

View file

@ -222,21 +222,25 @@ public class NetworkCatalogActivity extends NetworkBaseActivity implements UserR
} }
} }
private static NetworkTree.Key getLoadableNetworkTreeKey(NetworkTree tree) { private static NetworkTree getLoadableNetworkTree(NetworkTree tree) {
if ((tree instanceof NetworkAuthorTree || tree instanceof NetworkSeriesTree) while (tree instanceof NetworkAuthorTree || tree instanceof NetworkSeriesTree) {
&& tree.Parent instanceof NetworkTree) { if (tree.Parent instanceof NetworkTree) {
return getLoadableNetworkTreeKey((NetworkTree)tree.Parent); tree = (NetworkTree)tree.Parent;
} else {
return null;
} }
return tree.getUniqueKey(); }
return tree;
} }
@Override @Override
public void onModelChanged() { public void onModelChanged() {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
public void run() { public void run() {
final NetworkView networkView = NetworkView.Instance(); final NetworkTree tree = getLoadableNetworkTree(myTree);
final NetworkTree.Key key = getLoadableNetworkTreeKey(myTree); myInProgress =
myInProgress = key != null && networkView.isInitialized() && networkView.containsItemsLoadingRunnable(key); tree != null &&
ItemsLoadingService.getRunnable(tree) != null;
getListView().invalidateViews(); getListView().invalidateViews();
/* /*
@ -261,14 +265,11 @@ public class NetworkCatalogActivity extends NetworkBaseActivity implements UserR
} }
private void doStopLoading() { private void doStopLoading() {
if (NetworkView.Instance().isInitialized()) { final ItemsLoadingRunnable runnable = ItemsLoadingService.getRunnable(myTree);
final ItemsLoadingRunnable runnable =
NetworkView.Instance().getItemsLoadingRunnable(myTree.getUniqueKey());
if (runnable != null) { if (runnable != null) {
runnable.interruptLoading(); runnable.interruptLoading();
} }
} }
}
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {

View file

@ -200,13 +200,9 @@ public class NetworkLibraryActivity extends NetworkBaseActivity {
} }
private static boolean searchIsInProgress() { private static boolean searchIsInProgress() {
final NetworkView nView = NetworkView.Instance(); return ItemsLoadingService.getRunnable(
return NetworkLibrary.Instance().getSearchItemTree()
nView != null && ) != null;
nView.isInitialized() &&
nView.containsItemsLoadingRunnable(
NetworkLibrary.Instance().getSearchItemTree().getUniqueKey()
);
} }
@Override @Override

View file

@ -156,7 +156,7 @@ public class NetworkSearchActivity extends Activity {
final SearchItemTree tree = library.getSearchItemTree(); final SearchItemTree tree = library.getSearchItemTree();
if (tree == null || if (tree == null ||
NetworkView.Instance().containsItemsLoadingRunnable(tree.getUniqueKey())) { ItemsLoadingService.getRunnable(tree) != null) {
return; return;
} }
@ -167,10 +167,8 @@ public class NetworkSearchActivity extends Activity {
NetworkView.Instance().fireModelChangedAsync(); NetworkView.Instance().fireModelChangedAsync();
final SearchHandler handler = new SearchHandler(tree); final SearchHandler handler = new SearchHandler(tree);
NetworkView.Instance().startItemsLoading( ItemsLoadingService.start(
this, this, tree, new SearchRunnable(handler, pattern)
tree.getUniqueKey(),
new SearchRunnable(handler, pattern)
); );
Util.openTree(this, tree); Util.openTree(this, tree);
} }

View file

@ -134,46 +134,8 @@ class NetworkView {
* Code for loading network items (running items-loading service and managing items-loading runnables). * Code for loading network items (running items-loading service and managing items-loading runnables).
*/ */
private final HashMap<NetworkTree.Key,ItemsLoadingRunnable> myItemsLoadingRunnables =
new HashMap<NetworkTree.Key,ItemsLoadingRunnable>();
public void startItemsLoading(Context context, NetworkTree.Key key, ItemsLoadingRunnable runnable) {
boolean doDownload = false;
synchronized (myItemsLoadingRunnables) {
if (!myItemsLoadingRunnables.containsKey(key)) {
myItemsLoadingRunnables.put(key, runnable);
doDownload = true;
}
}
if (doDownload) {
context.startService(
new Intent(context.getApplicationContext(), ItemsLoadingService.class)
.putExtra(ItemsLoadingService.ITEMS_LOADING_RUNNABLE_KEY, key)
);
}
}
ItemsLoadingRunnable getItemsLoadingRunnable(NetworkTree.Key key) {
synchronized (myItemsLoadingRunnables) {
return myItemsLoadingRunnables.get(key);
}
}
void removeItemsLoadingRunnable(NetworkTree.Key key) {
synchronized (myItemsLoadingRunnables) {
ItemsLoadingRunnable runnable = myItemsLoadingRunnables.remove(key);
if (runnable != null) {
runnable.runFinishHandler();
}
}
}
public final boolean containsItemsLoadingRunnable(NetworkTree.Key key) {
return getItemsLoadingRunnable(key) != null;
}
public void tryResumeLoading(NetworkBaseActivity activity, NetworkCatalogTree tree, Runnable expandRunnable) { public void tryResumeLoading(NetworkBaseActivity activity, NetworkCatalogTree tree, Runnable expandRunnable) {
final ItemsLoadingRunnable runnable = getItemsLoadingRunnable(tree.getUniqueKey()); final ItemsLoadingRunnable runnable = ItemsLoadingService.getRunnable(tree);
if (runnable != null && runnable.tryResumeLoading()) { if (runnable != null && runnable.tryResumeLoading()) {
Util.openTree(activity, tree); Util.openTree(activity, tree);
return; return;

View file

@ -50,7 +50,7 @@ class SearchItemActions extends NetworkTreeActions {
public void buildContextMenu(Activity activity, ContextMenu menu, NetworkTree tree) { public void buildContextMenu(Activity activity, ContextMenu menu, NetworkTree tree) {
menu.setHeaderTitle(tree.getName()); menu.setHeaderTitle(tree.getName());
final boolean isLoading = NetworkView.Instance().containsItemsLoadingRunnable(tree.getUniqueKey()); final boolean isLoading = ItemsLoadingService.getRunnable(tree) != null;
if (!isLoading) { if (!isLoading) {
addMenuItem(menu, RUN_SEARCH_ITEM_ID, "search"); addMenuItem(menu, RUN_SEARCH_ITEM_ID, "search");
@ -61,7 +61,7 @@ class SearchItemActions extends NetworkTreeActions {
@Override @Override
public int getDefaultActionCode(NetworkBaseActivity activity, NetworkTree tree) { public int getDefaultActionCode(NetworkBaseActivity activity, NetworkTree tree) {
final boolean isLoading = NetworkView.Instance().containsItemsLoadingRunnable(tree.getUniqueKey()); final boolean isLoading = ItemsLoadingService.getRunnable(tree) != null;
if (!isLoading) { if (!isLoading) {
return RUN_SEARCH_ITEM_ID; return RUN_SEARCH_ITEM_ID;
} }

View file

@ -232,7 +232,7 @@ abstract class Util implements UserRegistrationConstants {
} }
} }
private static final String TREE_KEY_KEY = "org.geometerplus.android.fbreader.network.TreeKey"; static final String TREE_KEY_KEY = "org.geometerplus.android.fbreader.network.TreeKey";
static void openTree(Context context, NetworkTree tree) { static void openTree(Context context, NetworkTree tree) {
final Class<?> clz = tree instanceof NetworkBookTree final Class<?> clz = tree instanceof NetworkBookTree

View file

@ -109,6 +109,10 @@ public class NetworkBookItem extends NetworkItem {
IndexInSeries = indexInSeries; IndexInSeries = indexInSeries;
} }
public boolean isFullyLoaded() {
return true;
}
public void loadFullInformation() throws ZLNetworkException { public void loadFullInformation() throws ZLNetworkException {
} }

View file

@ -19,8 +19,7 @@
package org.geometerplus.fbreader.network; package org.geometerplus.fbreader.network;
import java.util.LinkedList; import java.util.*;
import java.util.Set;
import java.io.Serializable; import java.io.Serializable;
import org.geometerplus.zlibrary.core.image.ZLImage; import org.geometerplus.zlibrary.core.image.ZLImage;
@ -67,6 +66,9 @@ public abstract class NetworkTree extends FBTree {
} }
} }
private Key myKey;
private Map<String,Object> myUserData;
protected NetworkTree() { protected NetworkTree() {
super(); super();
} }
@ -123,10 +125,8 @@ public abstract class NetworkTree extends FBTree {
return null; return null;
} }
public abstract NetworkItem getHoldedItem(); public abstract NetworkItem getHoldedItem();
private Key myKey;
/** /**
* Returns unique identifier which can be used in NetworkView methods * Returns unique identifier which can be used in NetworkView methods
* @return unique Key instance * @return unique Key instance
@ -141,6 +141,21 @@ public abstract class NetworkTree extends FBTree {
return myKey; return myKey;
} }
public final synchronized void setUserData(String key, Object data) {
if (myUserData == null) {
myUserData = new HashMap<String,Object>();
}
if (data != null) {
myUserData.put(key, data);
} else {
myUserData.remove(key);
}
}
public final synchronized Object getUserData(String key) {
return myUserData != null ? myUserData.get(key) : null;
}
/** /**
* Returns id used as a part of unique key above. This string must be * Returns id used as a part of unique key above. This string must be
* not null * not null

View file

@ -208,6 +208,11 @@ public class OPDSBookItem extends NetworkBookItem implements OPDSConstants {
private volatile boolean myInformationIsFull; private volatile boolean myInformationIsFull;
@Override
public synchronized boolean isFullyLoaded() {
return myInformationIsFull || getUrl(UrlInfo.Type.SingleEntry) == null;
}
@Override @Override
public synchronized void loadFullInformation() throws ZLNetworkException { public synchronized void loadFullInformation() throws ZLNetworkException {
if (myInformationIsFull) { if (myInformationIsFull) {