2

I have a getViewBitmap() method that creates a Bitmap with a 3rd party library (which is proprietary) and goes like this:

public Bitmap getViewBitmap(int index) {
    Bitmap retBitmap = null;

    int width = 400;
    int height = 200;

    try {
        retBitmap = lib.createBitmap(width, height, index);
    } catch(BMException e) {
        e.printStacktrace();
    }

    return retBitmap;
}

This method is used for creating two page view bitmap in another method:

public Bitmap getTwoPageBitmap(int firstPageIndex, intSecondPageIndex) {
    Bitmap first = getViewBitmap(firstPageIndex);
    Bitmap second = getViewBitmap(secondPageIndex);

    Bitmap retBitmap = Bitmap.create(800, 400, first.getConfig());

    Canvas helperCanvas = new Canvas(splitViewBm);
    helperCanvas.drawBitmap(leftPageBitmap, 0, 0, null);
    helperCanvas.drawBitmap(rightPageBitmap, leftPageBitmap.getWidth(), 0, null);

    return retBitmap;
}

And then finally in initiated method, I have this:

public View createView() {
    MyView v = new MyView();
    if(pagePortratit) {
        v.setPageView(getViewBitmap(0));
    } else {
        // if page is landscape
        v.setPageView(getTwoPageBitmap(0, 1));
    }

    return v;
}

Now - I wanna make the getViewBitmap(int) method Asynchronous. Since the "lib.createBitmap(int, int, int)" is pretty slow and it blocks the UI, I want the creation of the bitmap (getViewBitmap(int)) to be in another thread, with possibility to interrupt it's work.

What is the correct design for such design so that the method that is actually heavy goes async?

Cays
  • 23
  • 2

2 Answers2

1

You likely want to subclass AsyncTask (read here) and put your getBitmapView code in the doInBackground() method (@Override). When it's done, have the onPostExecute() method update the View/UI. The logic for determining landscape or portrait will want to be outside the AsyncTask and you'll just want to farm out to the task (using .execute()) which ever view is needed.

That might be one approach.

Jack
  • 1,250
  • 1
  • 14
  • 26
  • Ok - I understand that, but then getTwoPageBitmap() should create two bitmaps - and since the task is Async - how would I know when the first one is created and when the second so that I merge them into one? – Cays Jul 17 '11 at 17:29
  • The method `onPostExecute` will fire when the operation is over. For each you could include some logic here or elsewhere to determine when one has finished. Check out this article for some more insight into this (they deal with Bitmaps here too): [http://developer.android.com/resources/articles/painless-threading.html](http://developer.android.com/resources/articles/painless-threading.html) – Jack Jul 17 '11 at 17:34
  • yeps - I will have to set some flag whether is one page or two page view. Thanks a lot! One more - how would I interrupt() the AsyncTask. I know there is .cancel(boolean) method - but that doesn't interrupt the asynctask. I need to execute this once and if another task is started to finish the previous one, to interrupt it. – Cays Jul 17 '11 at 17:36
  • Well, IIRC, calling `.cancel(true)` will attempt to interrupt the thread to stop the task: > If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task. Inside your running method, `doInBackground(...)`, you can check if it's been cancelled by calling `isCancelled()` and try to stop it quicker. See this: [AsyncTask#cancel(boolean)] (http://developer.android.com/reference/android/os/AsyncTask.html#cancel(boolean)) I think that addresses your question. – Jack Jul 17 '11 at 18:19
  • Jack: I really appreciate your help! May Thor bless you. Thanks – Cays Jul 17 '11 at 18:38
  • No problem, anytime. If you liked the answer, reward it and click the green arrow :-). Thanks! – Jack Jul 17 '11 at 19:20
0

I think the best thing that you can do is to use AysncTask which allows u to update the UI Directly without special handling for UI Thread update.

the100rabh
  • 4,077
  • 4
  • 32
  • 40