3
votes

My issue:

12-18 17:05:03.336: DEBUG/StrictMode(2112): StrictMode policy violation; ~duration=2073 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=23 violation=2

From the factory method

12-18 17:05:03.336: DEBUG/StrictMode(2112): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:299)

Then in my code

12-18 17:05:03.336: DEBUG/StrictMode(2112): at blah.ImageCache.getFromCache(ImageCache.java:248)

12-18 17:05:03.336: DEBUG/StrictMode(2112):
at blah2$LoaderThread$1.handleMessage(blah.java:63)

Important snip-its

class LoaderThread extends HandlerThread {

public Handler mHandler;

public LoaderThread(String name) { super(name); }

@Override public void onLooperPrepared(){ mHandler = new Handler(){ public void handleMessage(Message msg) { Bitmap bit =ImageCache.getInstance().getFromCache((String)msg.obj,ImageCache.USE_DISK); } }; } }

The getFromCache method in the ImageCache class calls

bitmap = BitmapFactory.decodeFile(fLoc);

Which seems to be running on the UI thread, but it makes no sense to me. Shouldn't this be getting called on a background thread? This was the goal of using HandlerThread after all...

The LoadThread class is created in my onCreate(bundle) like this

LoaderThread loader = new LoaderThread("imgLoader")

loader.start();

and messages are passed from the UI thread via the handler

loader.mHandler.dispatchMessage(loader.mHandler.obtainMessage(args..));

I'm wondering if this has to do with the getInstance method which is static

public static synchronized ImageCache getInstance() {

if (_instance==null) { _instance = new ImageCache(); } return _instance; }

1
@smith234: Why are you using HandlerThread instead of just an AsyncTask?CommonsWare
@CommonsWare I wanted to see how it performs with loading images in a ListView. With an AsyncTask I would have to spawn a new one for each drawable. With the HandlerThread I can just post messages to its looper (which loads the file from disk and posts a message back to the UI's looper which can update the row in question)smith324

1 Answers

3
votes

I feel like an ass now, but I was calling the wrong method on my handler...

the wrong way

loader.mHandler.dispatchMessage(loader.mHandler.obtainMessage(args..));

the right way

loader.mHandler.sendMessage(loader.mHandler.obtainMessage(args..));

So somehow the messages were being run through the handler still, just on the UI thread instead of the background one.