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

library loading in background

This commit is contained in:
Nikolay Pultsin 2011-07-17 21:39:01 +01:00
parent 9296b9df15
commit f40cb38c0b
5 changed files with 44 additions and 67 deletions

View file

@ -44,7 +44,7 @@ import org.geometerplus.android.fbreader.FBReader;
import org.geometerplus.android.fbreader.tree.BaseActivity; import org.geometerplus.android.fbreader.tree.BaseActivity;
import org.geometerplus.android.fbreader.tree.ListAdapter; import org.geometerplus.android.fbreader.tree.ListAdapter;
public class LibraryActivity extends BaseActivity implements MenuItem.OnMenuItemClickListener, View.OnCreateContextMenuListener { public class LibraryActivity extends BaseActivity implements MenuItem.OnMenuItemClickListener, View.OnCreateContextMenuListener, Library.ChangeListener {
public static final String SELECTED_BOOK_PATH_KEY = "SelectedBookPath"; public static final String SELECTED_BOOK_PATH_KEY = "SelectedBookPath";
static Library LibraryInstance; static Library LibraryInstance;
@ -65,6 +65,7 @@ public class LibraryActivity extends BaseActivity implements MenuItem.OnMenuItem
LibraryInstance = new Library(); LibraryInstance = new Library();
startService(new Intent(getApplicationContext(), InitializationService.class)); startService(new Intent(getApplicationContext(), InitializationService.class));
} }
LibraryInstance.addChangeListener(this);
final String selectedBookPath = getIntent().getStringExtra(SELECTED_BOOK_PATH_KEY); final String selectedBookPath = getIntent().getStringExtra(SELECTED_BOOK_PATH_KEY);
mySelectedBook = null; mySelectedBook = null;
@ -90,7 +91,10 @@ public class LibraryActivity extends BaseActivity implements MenuItem.OnMenuItem
@Override @Override
protected void onDestroy() { protected void onDestroy() {
if (LibraryInstance != null) {
LibraryInstance.removeChangeListener(this);
LibraryInstance = null; LibraryInstance = null;
}
super.onDestroy(); super.onDestroy();
} }
@ -318,4 +322,13 @@ public class LibraryActivity extends BaseActivity implements MenuItem.OnMenuItem
} }
getListView().invalidateViews(); getListView().invalidateViews();
} }
public void onLibraryChanged() {
runOnUiThread(new Runnable() {
public void run() {
getListAdapter().replaceAll(getCurrentTree().subTrees());
setProgressBarIndeterminateVisibility(!LibraryInstance.isSynchronized());
}
});
}
} }

View file

@ -72,8 +72,6 @@ public class NetworkBaseActivity extends BaseActivity implements NetworkView.Eve
OLD_STYLE_FLAG = true; OLD_STYLE_FLAG = true;
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
SQLiteCookieDatabase.init(this); SQLiteCookieDatabase.init(this);
Connection = new BookDownloaderServiceConnection(); Connection = new BookDownloaderServiceConnection();

View file

@ -24,8 +24,7 @@ import java.util.ArrayList;
import android.app.ListActivity; import android.app.ListActivity;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.KeyEvent; import android.view.*;
import android.view.View;
import org.geometerplus.android.util.UIUtil; import org.geometerplus.android.util.UIUtil;
@ -48,6 +47,7 @@ public abstract class BaseActivity extends ListActivity {
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
super.onCreate(icicle); super.onCreate(icicle);
Thread.setDefaultUncaughtExceptionHandler(new org.geometerplus.zlibrary.ui.android.library.UncaughtExceptionHandler(this)); Thread.setDefaultUncaughtExceptionHandler(new org.geometerplus.zlibrary.ui.android.library.UncaughtExceptionHandler(this));
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
} }
@Override @Override

View file

@ -60,24 +60,6 @@ public class FirstLevelTree extends LibraryTree {
return myId; return myId;
} }
@Override
public Status getOpeningStatus() {
return
myLibrary.hasState(Library.STATE_FULLY_INITIALIZED)
? Status.READY_TO_OPEN
: Status.WAIT_FOR_OPEN;
}
@Override
public String getOpeningStatusMessage() {
return "loadingBookList";
}
@Override
public void waitForOpening() {
myLibrary.waitForState(Library.STATE_FULLY_INITIALIZED);
}
@Override @Override
public boolean isSelectable() { public boolean isSelectable() {
return false; return false;

View file

@ -34,8 +34,9 @@ import org.geometerplus.fbreader.formats.PluginCollection;
import org.geometerplus.fbreader.Paths; import org.geometerplus.fbreader.Paths;
public final class Library { public final class Library {
static final int STATE_NOT_INITIALIZED = 0; public interface ChangeListener {
static final int STATE_FULLY_INITIALIZED = 1; void onLibraryChanged();
}
public static final String ROOT_FAVORITES = "favorites"; public static final String ROOT_FAVORITES = "favorites";
public static final String ROOT_SEARCH_RESULTS = "searchResults"; public static final String ROOT_SEARCH_RESULTS = "searchResults";
@ -53,8 +54,8 @@ public final class Library {
private final RootTree myRootTree = new RootTree(this); private final RootTree myRootTree = new RootTree(this);
private boolean myDoGroupTitlesByFirstLetter; private boolean myDoGroupTitlesByFirstLetter;
private volatile int myState = STATE_NOT_INITIALIZED; private final List<ChangeListener> myListeners = new LinkedList<ChangeListener>();
private volatile boolean myInterrupted = false; private volatile boolean myIsSynchronized = false;
public Library() { public Library() {
new FavoritesTree(myRootTree, ROOT_FAVORITES); new FavoritesTree(myRootTree, ROOT_FAVORITES);
@ -73,6 +74,14 @@ public final class Library {
return (FirstLevelTree)myRootTree.getSubTree(key); return (FirstLevelTree)myRootTree.getSubTree(key);
} }
public synchronized void addChangeListener(ChangeListener listener) {
myListeners.add(listener);
}
public synchronized void removeChangeListener(ChangeListener listener) {
myListeners.remove(listener);
}
public LibraryTree getLibraryTree(LibraryTree.Key key) { public LibraryTree getLibraryTree(LibraryTree.Key key) {
if (key == null) { if (key == null) {
return null; return null;
@ -84,23 +93,6 @@ public final class Library {
return parentTree != null ? (LibraryTree)parentTree.getSubTree(key.Id) : null; return parentTree != null ? (LibraryTree)parentTree.getSubTree(key.Id) : null;
} }
boolean hasState(int state) {
return myState >= state || myInterrupted;
}
void waitForState(int state) {
while (myState < state && !myInterrupted) {
synchronized (this) {
if (myState < state && !myInterrupted) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
}
}
public static ZLResourceFile getHelpFile() { public static ZLResourceFile getHelpFile() {
final Locale locale = Locale.getDefault(); final Locale locale = Locale.getDefault();
@ -271,8 +263,10 @@ public final class Library {
} }
} }
private void fireModelChangedEvent() { private synchronized void fireModelChangedEvent() {
System.err.println("model changed event"); for (ChangeListener l : myListeners) {
l.onLibraryChanged();
}
} }
private void build() { private void build() {
@ -384,30 +378,26 @@ public final class Library {
} }
}); });
db.setExistingFlag(newBooks, true); db.setExistingFlag(newBooks, true);
myState = STATE_FULLY_INITIALIZED;
} }
public synchronized void synchronize() { public void synchronize() {
if (myState == STATE_NOT_INITIALIZED) {
try {
myInterrupted = false;
build(); build();
} catch (Throwable t) { myIsSynchronized = true;
myInterrupted = true; fireModelChangedEvent();
}
notifyAll();
} }
public boolean isSynchronized() {
return myIsSynchronized;
} }
public static Book getRecentBook() { public static Book getRecentBook() {
List<Long> recentIds = BooksDatabase.Instance().loadRecentBookIds(); List<Long> recentIds = BooksDatabase.Instance().loadRecentBookIds();
return (recentIds.size() > 0) ? Book.getById(recentIds.get(0)) : null; return recentIds.size() > 0 ? Book.getById(recentIds.get(0)) : null;
} }
public static Book getPreviousBook() { public static Book getPreviousBook() {
List<Long> recentIds = BooksDatabase.Instance().loadRecentBookIds(); List<Long> recentIds = BooksDatabase.Instance().loadRecentBookIds();
return (recentIds.size() > 1) ? Book.getById(recentIds.get(1)) : null; return recentIds.size() > 1 ? Book.getById(recentIds.get(1)) : null;
} }
private FirstLevelTree createNewSearchResults(String pattern) { private FirstLevelTree createNewSearchResults(String pattern) {
@ -419,7 +409,6 @@ public final class Library {
} }
public LibraryTree searchBooks(String pattern) { public LibraryTree searchBooks(String pattern) {
waitForState(STATE_FULLY_INITIALIZED);
FirstLevelTree newSearchResults = null; FirstLevelTree newSearchResults = null;
if (pattern != null) { if (pattern != null) {
pattern = pattern.toLowerCase(); pattern = pattern.toLowerCase();
@ -451,7 +440,6 @@ public final class Library {
if (book == null) { if (book == null) {
return false; return false;
} }
waitForState(STATE_FULLY_INITIALIZED);
final LibraryTree rootFavorites = getFirstLevelTree(ROOT_FAVORITES); final LibraryTree rootFavorites = getFirstLevelTree(ROOT_FAVORITES);
for (FBTree tree : rootFavorites.subTrees()) { for (FBTree tree : rootFavorites.subTrees()) {
if (tree instanceof BookTree && book.equals(((BookTree)tree).Book)) { if (tree instanceof BookTree && book.equals(((BookTree)tree).Book)) {
@ -462,7 +450,6 @@ public final class Library {
} }
public void addBookToFavorites(Book book) { public void addBookToFavorites(Book book) {
waitForState(STATE_FULLY_INITIALIZED);
if (isBookInFavorites(book)) { if (isBookInFavorites(book)) {
return; return;
} }
@ -472,7 +459,6 @@ public final class Library {
} }
public void removeBookFromFavorites(Book book) { public void removeBookFromFavorites(Book book) {
waitForState(STATE_FULLY_INITIALIZED);
if (getFirstLevelTree(ROOT_FAVORITES).removeBook(book)) { if (getFirstLevelTree(ROOT_FAVORITES).removeBook(book)) {
BooksDatabase.Instance().removeFromFavorites(book.getId()); BooksDatabase.Instance().removeFromFavorites(book.getId());
} }
@ -484,7 +470,6 @@ public final class Library {
public static final int REMOVE_FROM_LIBRARY_AND_DISK = REMOVE_FROM_LIBRARY | REMOVE_FROM_DISK; public static final int REMOVE_FROM_LIBRARY_AND_DISK = REMOVE_FROM_LIBRARY | REMOVE_FROM_DISK;
public int getRemoveBookMode(Book book) { public int getRemoveBookMode(Book book) {
waitForState(STATE_FULLY_INITIALIZED);
return canDeleteBookFile(book) ? REMOVE_FROM_DISK : REMOVE_DONT_REMOVE; return canDeleteBookFile(book) ? REMOVE_FROM_DISK : REMOVE_DONT_REMOVE;
} }
@ -506,7 +491,6 @@ public final class Library {
if (removeMode == REMOVE_DONT_REMOVE) { if (removeMode == REMOVE_DONT_REMOVE) {
return; return;
} }
waitForState(STATE_FULLY_INITIALIZED);
myBooks.remove(book); myBooks.remove(book);
if (getFirstLevelTree(ROOT_RECENT).removeBook(book)) { if (getFirstLevelTree(ROOT_RECENT).removeBook(book)) {
final BooksDatabase db = BooksDatabase.Instance(); final BooksDatabase db = BooksDatabase.Instance();