mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-05 02:39:23 +02:00
library loading in background
This commit is contained in:
parent
9296b9df15
commit
f40cb38c0b
5 changed files with 44 additions and 67 deletions
|
@ -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() {
|
||||||
LibraryInstance = null;
|
if (LibraryInstance != null) {
|
||||||
|
LibraryInstance.removeChangeListener(this);
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
build();
|
||||||
try {
|
myIsSynchronized = true;
|
||||||
myInterrupted = false;
|
fireModelChangedEvent();
|
||||||
build();
|
}
|
||||||
} catch (Throwable t) {
|
|
||||||
myInterrupted = true;
|
public boolean isSynchronized() {
|
||||||
}
|
return myIsSynchronized;
|
||||||
notifyAll();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue