我的线程具有优先设置为Thread.MIN_PRIORITY + 1
的线程,该线程为我进行一些图像处理(调整,阅读和写作)。
我注意到,每当该线程在图像上工作时,我的UI线程中的动画就会开始口吃和冻结。
优先级足够低,因此动画应比该线程更高的优先级,而我的CPU肯定不会饿死。
这可能会发生任何特殊原因?
编辑 - 我的线程:
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();
}
});
}
}
可能是gc。
图像处理可能需要大量的内存分配和随之而来的垃圾收集。Android中的GC使用Mark-Sweep算法,该算法需要VM停止执行程序 - 您可以看到这可能会导致UI口吃。例如,请参见此答案和此免费报价:
标记方法的主要缺点是那个正常程序 在运行垃圾收集算法时,执行被暂停。特别是 可以是与人用户互动的程序中的问题,也可能是必须满足真实的问题 时间执行约束。例如,使用标记和的交互式应用程序 扫描垃圾收集定期不反应。
您可以通过查看logcat确认这是否正确 - 这将为每个GC打印出一条消息,在此时间,UI线程将被阻止。
如果是GC,那么解决的一种方法是查看您的内存分配模式,看看是否可以通过重复使用缓冲区和工作内存来减少内存流失。
lazylist可以帮助您。
这是开源的,将图像加载在其他线程中并在UI上显示
您应该使用AsyncTask
处理和显示位图:
https://developer.android.com/training/displaying-bitmaps/process-bitmap.html#async-task
此类专门为此使用而设计,即为什么在线程上发生这种情况,这可能与Android如何与常规Java应用程序不同地处理GC有关。处理ListView
或GridView
中显示的Bitmap
对象时尤其如此。