在我的Android应用程序中,我从云端下载图像。下载是在一个线程中执行的,在同一个线程中,我还使用新下载的图像设置了一个图像视图。设置完图像后,我会调用postinvalidate()
。
然而,图像不会立即显示出来。有没有办法让重绘立即发生?我需要一种触发绘图周期的方法。
答案 0 :(得分:41)
从View类派生的每个类都有invalidate()
和postInvalidate()
方法。如果调用invalidate()
,它会告诉系统当前视图已更改,并且应该尽快重新绘制 。由于此方法只能通过 UIThread 调用,因此当您在 UIThread 中不时仍需要另一种方法,并且仍希望通知系统您的视图已更改。 postInvalidate()
方法会通过非UIThread 通知系统,并且会尽快在UIThread上的 next eventloop 中重新绘制视图。
在你的情况下,你可以在AsyncTask
(一个智能的背景线程)的帮助下实现你想要的.AsyncTask可以正确,方便地使用UI线程。此类允许执行后台操作(在您的情况下在后台下载图像)并在UI线程上发布结果(将位图设置为ImageView),而无需操纵线程和/或处理程序。
异步任务由在后台线程上运行的计算定义,其结果在UI线程上发布。异步任务由 3泛型定义,称为Params,Progress和Result, 4步,称为begin,doInBackground,processProgress和end。
4个步骤
执行异步任务时,任务将经历4个步骤:
onPreExecute()
,在执行任务后立即在UI线程上调用。此步骤通常用于设置任务,例如在从云下载图像之前在用户界面中显示进度条,并用于提供良好的用户体验。
doInBackground(Params...)
,在onPreExecute()完成执行后立即在后台线程上调用。此步骤用于执行可能需要很长时间的后台计算。异步任务的参数将传递给此步骤。计算结果必须由此步骤返回,并将传递回最后一步。此步骤还可以使用publishProgress(Progress ...)发布一个或多个进度单元。这些值发布在UI线程的onProgressUpdate(Progress ...)步骤中。
onProgressUpdate(Progress...)
,在调用publishProgress(Progress...)
后在UI线程上调用。执行的时间是不确定的。此方法用于在后台计算仍在执行时显示用户界面中的任何形式的进度。
onPostExecute(Result)
,在后台计算完成后在UI线程上调用。后台计算的结果作为参数传递给此步骤,您可以将位图设置为imageView并使视图无效
答案 1 :(得分:3)
无效无效。暂时更改uri或url或图像的路径并更改回所需的路径。例如,如果我有
image_url="myhost/img.png";
himg.setImageURI(image_url, imageLoader);
我可以将其刷新为:
himg.setImageURI(null, imageLoader);
himg.setImageURI(image_url, imageLoader)
答案 2 :(得分:2)
您尝试使用invalidate()
了吗?它会强制立即重新绘制视图,而不是在下一个循环中重绘
答案 3 :(得分:0)
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (!socket.isClosed()) {
imgArray = receiveImagebytes();
}
}
}).start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (!socket.isClosed()) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
imageView.setImageBitmap(BitmapFactory.decodeByteArray(imgArray, 0, imgArray.length));
imageView.invalidate();
}
});