views:

176

answers:

2

I have been trying to optimize my single thread app which loads a bunch of tiles that makeup a large bitmap. The app was becoming very sluggish when it would load the new tiles into system memory. Im now looking trying to use Async Tasks for this purpose. The app detects which tile is in the top left in a method called by onDraw, creates a string that contains the path of the bitmap in the Assets folder, and then checks to see if the bitmap is null before drawing. If it is null, it will load it into memory. My idea was to process the bitmap in DoBackground, and in postExecute trigger a view invalidate to display the async loaded bitmap. Few questions:

1.) can i execute my aSync task for each bitmap? (this statement: new myAsyncTaskManager().execute(bitmapPath); if not, what is the best way to go about it since the only thing aSync will do is just load bitmaps into memory?

2.) Is it possible to set the priority aSyncTask if the bitmaps load too slow?

3.) Is there a better way to go about this? im certain it is the bitmap loading, and not the canvas drawing that slows down the app.

My temporary aSync code:

private class myAsyncTaskManager extends AsyncTask<String, Void, String> {

@Override
protected String doInBackground(String... bitmapPath) {
      Log.e("sys","i ran using aTask");
        try {

            bitmapArray[rectBeingDrawn] = BitmapFactory.decodeStream(assetManager.open(imagePathToLoad));


        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }       return null;
}


@Override
protected void onPostExecute(String result) {
    // execution of result of Long time consuming operation
    mCampusMap.invalidate();
}
}
+1  A: 

Wait, you're calling bitmapLoaderThread.run()? It's kind of hard to figure out what's going on because these are code snippets with no context (what thread is something running on? What function?), but you don't call run() - that's the operating system's job! To start a new thread, you call start() - this will create the new thread and call its run() function. If you call run directly, you're still calling it in your own thread!

Other than that - how do you do the handshake between the two threads? How does the worker thread tell the main thread that the bitmap is loaded? You can use a Handler for that, or you can use an AsyncTask instead of the Thread altogether.

EboMike
@EboMike, that makes a lot of sense thanks. I rewrote my entire question and setup some preliminary code for my bitmaps to be loaded using aSyncTask.
Evan Kimia
+2  A: 

Adding a new answer to your completely new question :)

  1. Depends on the amount of bitmaps. How many do you have? You don't want to create dozens of threads. After all, you only have one core on your hardware, so having multiple threads won't buy you anything - the context switching would just drown it out. If you have tons of bitmaps, you may want to have a queue of bitmaps and work through it. For that, a Thread and Handler would actually be better.

  2. It is. Generally, I set worker threads one priority level lower than the main thread.

EboMike
There are 416 tiles. There is an average of 15 bitmaps being drawn for a high res. device like my droid with a 854 by 480 resolution, and it will typically load 5 bitmaps into memory as you are scrolling down. So if i were to go the thread route, i would I effectively call the thread to load the bitmap? I dont think i have to return anything since the UI thread will automatically draw the bitmaps once it detects that they are not null. I see that by running myThread.run(); earlier didnt work as well as i hoped ha.
Evan Kimia