Question

I have a thread with a priority set to Thread.MIN_PRIORITY + 1 that does some image processing for me (resizing, reading and writing).

I've noticed that whenever that thread is working on an image, animations in my UI thread start to stutter and freeze up.

The priority is low enough such that animations should take a higher priority over that thread, and my CPU certainly isn't starved for resources.

Is there any particular reason this might be happening?


Edit - my thread:

public class WorkerQueue extends Thread {
  public Handler handler;
  int priority = Thread.MIN_PRIORITY + 1;
  private static WorkerQueue self = null;

  public static WorkerQueue getInstance() {
    if (self == null) {
      self = new WorkerQueue();
      self.start();
      self.setPriority(priority);
    }

    return self;
  }

  @Override
  public void run() {
      Looper.prepare();
      handler = new Handler();
      handler.getLooper().getThread().setPriority(priority);
      Looper.loop();    
  }

  public synchronized void enqueueTask(final Worker task) {
    handler.post(new Runnable() {
      @Override
      public void run() {
          task.run();
      }
    });
  }
}
Was it helpful?

Solution

It may be GC.

Image processing can require a lot of memory allocations and consequent garbage collection. GCs in Android use the mark-and-sweep algorithm which requires the VM to stop execution of your program - you can see how this can cause UI stuttering. See for example this answer and this on-the-money quote:

The main disadvantage of the mark-and-sweep approach is the fact that that normal program execution is suspended while the garbage collection algorithm runs. In particular, this can be a problem in a program that interacts with a human user or that must satisfy real time execution constraints. For example, an interactive application that uses mark-and sweep garbage collection becomes unresponsive periodically.

You can confirm whether this is correct by looking at logcat - this prints out a message for every GC, and for that time, the UI thread will be blocked.

If it is GC, then one approach to resolve it would be to look at your memory allocation patterns and see if you can reduce memory churn, maybe by reusing buffers and working memory.

OTHER TIPS

LazyList can help you.
This is open source that loading image in other thread and display on UI when it finish

You should be using AsyncTask to process and display bitmaps:

https://developer.android.com/training/displaying-bitmaps/process-bitmap.html#async-task

This class specifically designed for this usage, as to why this is happening on your Thread it is probably related to how Android handles GC differently to regular Java applications. This is especially true when dealing with Bitmap objects displayed in a ListView or GridView.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top