diff --git a/src/org/geometerplus/android/fbreader/image/ImageViewActivity.java b/src/org/geometerplus/android/fbreader/image/ImageViewActivity.java index 6203aadd9e9..9d8e1da5d4f 100644 --- a/src/org/geometerplus/android/fbreader/image/ImageViewActivity.java +++ b/src/org/geometerplus/android/fbreader/image/ImageViewActivity.java @@ -23,6 +23,7 @@ import android.content.Intent; import android.graphics.*; import android.net.Uri; +import android.os.AsyncTask; import android.os.Bundle; import android.util.FloatMath; import android.view.*; @@ -68,19 +69,31 @@ protected void onCreate(Bundle icicle) { final Uri uri = intent.getData(); if (ZLFileImage.SCHEME.equals(uri.getScheme())) { - final ZLFileImage image = ZLFileImage.byUrlPath(uri.getPath()); - if (image == null) { - // TODO: error message (?) - finish(); - } - try { - final ZLImageData imageData = ZLImageManager.Instance().getImageData(image); - myBitmap = ((ZLAndroidImageData)imageData).getFullSizeBitmap(); - } catch (Exception e) { - // TODO: error message (?) - e.printStackTrace(); - finish(); - } + new AsyncTask() { + protected Boolean doInBackground(Uri... args) { + Uri uri = args[0]; + final ZLFileImage image = ZLFileImage.byUrlPath(uri.getPath()); + if (image == null) { + return false; + } + + try { + final ZLImageData imageData = ZLImageManager.Instance().getImageData(image); + myBitmap = ((ZLAndroidImageData)imageData).getFullSizeBitmap(); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + + protected void onPostExecute(Boolean result) { + if(!result) { + // TODO: error message (?) + finish(); + } + } + }.execute(uri); } else { // TODO: error message (?) finish(); diff --git a/src/org/geometerplus/android/fbreader/library/BookInfoActivity.java b/src/org/geometerplus/android/fbreader/library/BookInfoActivity.java index 4a24e26bc15..b4566702999 100644 --- a/src/org/geometerplus/android/fbreader/library/BookInfoActivity.java +++ b/src/org/geometerplus/android/fbreader/library/BookInfoActivity.java @@ -27,6 +27,7 @@ import android.content.Intent; import android.content.res.ColorStateList; import android.graphics.Bitmap; +import android.os.AsyncTask; import android.os.Bundle; import android.text.method.LinkMovementMethod; import android.util.DisplayMetrics; @@ -113,14 +114,22 @@ public void onClick(View view) { setupButton(R.id.book_info_button_reload, "reloadInfo", new View.OnClickListener() { public void onClick(View view) { if (myBook != null) { - myBook.reloadInfoFromFile(); - setupBookInfo(myBook); - myDontReloadBook = false; - myCollection.bindToService(BookInfoActivity.this, new Runnable() { - public void run() { - myCollection.saveBook(myBook); + new AsyncTask() { + protected Void doInBackground(Void... args) { + myBook.reloadInfoFromFile(); + return null; } - }); + + protected void onPostExecute(Void result) { + setupBookInfo(myBook); + myDontReloadBook = false; + myCollection.bindToService(BookInfoActivity.this, new Runnable() { + public void run() { + myCollection.saveBook(myBook); + } + }); + } + }.execute(); } } }); @@ -193,33 +202,44 @@ private void setupCover(Book book) { coverView.setVisibility(View.GONE); coverView.setImageDrawable(null); - final ZLImage image = BookUtil.getCover(book); + new AsyncTask() { + Bitmap coverBitmap; + protected Boolean doInBackground(Book... args) { + Book book = args[0]; + final ZLImage image = BookUtil.getCover(book); - if (image == null) { - return; - } + if (image == null) { + return false; + } - if (image instanceof ZLLoadableImage) { - final ZLLoadableImage loadableImage = (ZLLoadableImage)image; - if (!loadableImage.isSynchronized()) { - loadableImage.synchronize(); - } - } - final ZLAndroidImageData data = - ((ZLAndroidImageManager)ZLAndroidImageManager.Instance()).getImageData(image); - if (data == null) { - return; - } + if (image instanceof ZLLoadableImage) { + final ZLLoadableImage loadableImage = (ZLLoadableImage)image; + if (!loadableImage.isSynchronized()) { + loadableImage.synchronize(); + } + } + final ZLAndroidImageData data = + ((ZLAndroidImageManager)ZLAndroidImageManager.Instance()).getImageData(image); + if (data == null) { + return false; + } - final Bitmap coverBitmap = data.getBitmap(2 * maxWidth, 2 * maxHeight); - if (coverBitmap == null) { - return; - } + coverBitmap = data.getBitmap(2 * maxWidth, 2 * maxHeight); + if (coverBitmap == null) { + return false; + } + return true; + } - coverView.setVisibility(View.VISIBLE); - coverView.getLayoutParams().width = maxWidth; - coverView.getLayoutParams().height = maxHeight; - coverView.setImageBitmap(coverBitmap); + protected void onPostExecute(Boolean result) { + if(result) { + coverView.setVisibility(View.VISIBLE); + coverView.getLayoutParams().width = maxWidth; + coverView.getLayoutParams().height = maxHeight; + coverView.setImageBitmap(coverBitmap); + } + } + }.execute(book); } private void setupBookInfo(Book book) { diff --git a/src/org/geometerplus/android/fbreader/library/LibraryActivity.java b/src/org/geometerplus/android/fbreader/library/LibraryActivity.java index c3c3221b0e8..a17dd6d6555 100644 --- a/src/org/geometerplus/android/fbreader/library/LibraryActivity.java +++ b/src/org/geometerplus/android/fbreader/library/LibraryActivity.java @@ -22,6 +22,7 @@ import android.app.AlertDialog; import android.app.SearchManager; import android.content.*; +import android.os.AsyncTask; import android.os.Bundle; import android.view.*; import android.widget.AdapterView; @@ -220,24 +221,57 @@ private boolean onContextItemSelected(int itemId, Book book) { return true; case ADD_TO_FAVORITES_ITEM_ID: book.addLabel(Book.FAVORITE_LABEL); - myRootTree.Collection.saveBook(book); + new AsyncTask() { + protected Void doInBackground(Book... args) { + Book book = args[0]; + myRootTree.Collection.saveBook(book); + return null; + } + }.execute(book); return true; case REMOVE_FROM_FAVORITES_ITEM_ID: book.removeLabel(Book.FAVORITE_LABEL); - myRootTree.Collection.saveBook(book); - if (getCurrentTree().onBookEvent(BookEvent.Updated, book)) { - getListAdapter().replaceAll(getCurrentTree().subtrees(), true); - } + new AsyncTask() { + protected Book doInBackground(Book... args) { + Book book = args[0]; + myRootTree.Collection.saveBook(book); + return book; + } + + protected void onPostExecute(Book book) { + if (getCurrentTree().onBookEvent(BookEvent.Updated, book)) { + getListAdapter().replaceAll(getCurrentTree().subtrees(), true); + } + } + }.execute(book); return true; case MARK_AS_READ_ITEM_ID: book.addLabel(Book.READ_LABEL); - myRootTree.Collection.saveBook(book); - getListView().invalidateViews(); + new AsyncTask() { + protected Void doInBackground(Book... args) { + Book book = args[0]; + myRootTree.Collection.saveBook(book); + return null; + } + + protected void onPostExecute(Void v) { + getListView().invalidateViews(); + } + }.execute(book); return true; case MARK_AS_UNREAD_ITEM_ID: book.removeLabel(Book.READ_LABEL); - myRootTree.Collection.saveBook(book); - getListView().invalidateViews(); + new AsyncTask() { + protected Void doInBackground(Book... args) { + Book book = args[0]; + myRootTree.Collection.saveBook(book); + return null; + } + + protected void onPostExecute(Void v) { + getListView().invalidateViews(); + } + }.execute(book); return true; case DELETE_BOOK_ITEM_ID: tryToDeleteBook(book); @@ -367,5 +401,5 @@ public void onBookEvent(BookEvent event, Book book) { public void onBuildEvent(IBookCollection.Status status) { setProgressBarIndeterminateVisibility(!status.IsCompleted); - } + } } diff --git a/src/org/geometerplus/android/fbreader/network/NetworkBookInfoActivity.java b/src/org/geometerplus/android/fbreader/network/NetworkBookInfoActivity.java index 4a5ca640950..4774afe4733 100644 --- a/src/org/geometerplus/android/fbreader/network/NetworkBookInfoActivity.java +++ b/src/org/geometerplus/android/fbreader/network/NetworkBookInfoActivity.java @@ -26,6 +26,7 @@ import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.net.Uri; +import android.os.AsyncTask; import android.os.Bundle; import android.text.method.LinkMovementMethod; import android.util.DisplayMetrics; @@ -308,7 +309,6 @@ private final void setupCover() { final int maxHeight = metrics.heightPixels * 2 / 3; final int maxWidth = maxHeight * 2 / 3; - Bitmap coverBitmap = null; final ZLImage cover = NetworkTree.createCover(myBook); if (cover != null) { ZLAndroidImageData data = null; @@ -334,15 +334,24 @@ public void run() { data = mgr.getImageData(cover); } if (data != null) { - coverBitmap = data.getBitmap(maxWidth, maxHeight); + new AsyncTask() { + protected Bitmap doInBackground(ZLAndroidImageData... args) { + ZLAndroidImageData data = args[0]; + Bitmap coverBitmap = data.getBitmap(maxWidth, maxHeight); + return coverBitmap; + } + + protected void onPostExecute(Bitmap coverBitmap) { + if (coverBitmap != null) { + coverView.setImageBitmap(coverBitmap); + coverView.setVisibility(View.VISIBLE); + } else { + coverView.setVisibility(View.GONE); + } + } + }.execute(data); } } - if (coverBitmap != null) { - coverView.setImageBitmap(coverBitmap); - coverView.setVisibility(View.VISIBLE); - } else { - coverView.setVisibility(View.GONE); - } } private final void setupButtons() { diff --git a/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidPaintContext.java b/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidPaintContext.java index fe48e6af2f3..b98bfa02fb8 100644 --- a/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidPaintContext.java +++ b/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidPaintContext.java @@ -19,7 +19,12 @@ package org.geometerplus.zlibrary.ui.android.view; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + import android.graphics.*; +import android.os.AsyncTask; import org.geometerplus.zlibrary.core.image.ZLImageData; import org.geometerplus.zlibrary.core.util.ZLColor; @@ -289,29 +294,50 @@ public void drawString(int x, int y, char[] string, int offset, int length) { } @Override - public Size imageSize(ZLImageData imageData, Size maxSize, ScalingType scaling) { - final Bitmap bitmap = ((ZLAndroidImageData)imageData).getBitmap(maxSize, scaling); - return (bitmap != null && !bitmap.isRecycled()) - ? new Size(bitmap.getWidth(), bitmap.getHeight()) : null; + public Size imageSize(final ZLImageData imageData, final Size maxSize, final ScalingType scaling) { + try { + final Bitmap bitmap = new AsyncTask() { + protected Bitmap doInBackground(java.lang.Object... asyncTaskArgs) { + final Bitmap bitmap = ((ZLAndroidImageData)imageData).getBitmap(maxSize, scaling); + return bitmap; + } + }.execute().get(5000, TimeUnit.MILLISECONDS); // wait for max 5 seconds + return (bitmap != null && !bitmap.isRecycled()) + ? new Size(bitmap.getWidth(), bitmap.getHeight()) : null; + } catch (InterruptedException e) { + return null; + } catch (ExecutionException e) { + return null; + } catch (TimeoutException e) { + return null; + } } @Override - public void drawImage(int x, int y, ZLImageData imageData, Size maxSize, ScalingType scaling, ColorAdjustingMode adjustingMode) { - final Bitmap bitmap = ((ZLAndroidImageData)imageData).getBitmap(maxSize, scaling); - if (bitmap != null && !bitmap.isRecycled()) { - switch (adjustingMode) { - case LIGHTEN_TO_BACKGROUND: - myFillPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN)); - break; - case DARKEN_TO_BACKGROUND: - myFillPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN)); - break; - case NONE: - break; + public void drawImage(final int x, final int y, final ZLImageData imageData, final Size maxSize, final ScalingType scaling, final ColorAdjustingMode adjustingMode) { + new AsyncTask() { + protected Bitmap doInBackground(java.lang.Object... asyncTaskArgs) { + final Bitmap bitmap = ((ZLAndroidImageData)imageData).getBitmap(maxSize, scaling); + return bitmap; } - myCanvas.drawBitmap(bitmap, x, y - bitmap.getHeight(), myFillPaint); - myFillPaint.setXfermode(null); - } + + protected void onPostExecute(final Bitmap bitmap) { + if (bitmap != null && !bitmap.isRecycled()) { + switch (adjustingMode) { + case LIGHTEN_TO_BACKGROUND: + myFillPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN)); + break; + case DARKEN_TO_BACKGROUND: + myFillPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN)); + break; + case NONE: + break; + } + myCanvas.drawBitmap(bitmap, x, y - bitmap.getHeight(), myFillPaint); + myFillPaint.setXfermode(null); + } + } + }.execute(); } @Override