我在下载图像和更新ImageView时遇到问题,我正在使用ExecutorServices下载图像,但我面临的问题是,作为场景,我正在使用基本适配器在列表中显示Imageview。图像被下载,但这两个图像都只在firstImage View中更新。
所以位图在同一个imageView中得到了更新,有人遇到过类似的问题吗
例如,我正在下载2个图像,它正在创建2个ImageDownloader实例,所有运行良好,直到下载前部分行中的该类的Run(),一旦图像被下载,我得到了第一个图像下载器类的ImageView的对象引用,我不知道为什么?我认为它与listview或适配器无关,它更多的是与执行器和可运行实现相关,
公共类ImageLoader{
ExecutorService mExecutorService = null;
static ImageLoader mLoader = null;
Handler mImageHandler = null ;
DisplayMetrics mDisplayMetrics = null;
int mRequiredWidth =0 , mRequiredHeight = 0;
Map<String,ImageView> mToLoadObjects = Collections.synchronizedMap(
new WeakHashMap<String, ImageView>());
ArrayList<String> toloadURL = new ArrayList<String>();
protected Resources mResources = null;
MyImageCache mMemoryCache;
Activity activity;
public static final String LOGGER = "ImageLoader";
public ImageLoader(Activity context){
mExecutorService = Executors.newFixedThreadPool(5);
mImageHandler = new Handler();
mResources = context.getResources();
activity = context;
mMemoryCache = new MyImageCache();
mDisplayMetrics = context.getResources().getDisplayMetrics();
mRequiredWidth = mDisplayMetrics.widthPixels;
mRequiredHeight = mDisplayMetrics.heightPixels;
}
public void loadImage (String url,ImageView imageView){
try {
if (imageView != null) {
if (!toloadURL.contains(url)) {
toloadURL.add(url);
mExecutorService.execute(new ImageDownloader(url,imageView));
}
}
}catch (Exception e){
Log.v("Exception Occurs>>",""+e.getMessage());
}
}
class ImageDownloader implements Runnable{
String imageUrl;
ImageView downloadableImageView;
ImageDownloader loader;
ImageDownloader(String url,ImageView view){
Log.v(LOGGER,"Within ImageDownloader "+url +"this>>>"+this);
loader = this;
imageUrl = url;
downloadableImageView = view;
Log.v(LOGGER,"Within ImageDownloader "+downloadableImageView.getTag()+"this>>>"+this);
}
@Override
public void run() {
Log.v(LOGGER, "run" + downloadableImageView.getTag()+"this>>>>>"+this);
Bitmap tempBitmap = null;
tempBitmap = (mMemoryCache.getBitmapFromMemCache(imageUrl));
try{
if(tempBitmap!=null){
Log.v(LOGGER,"ImageBitmap Wid>>>>>>"+downloadableImageView.getTag()+"this>>>>"+this+""+tempBitmap.getWidth());
Log.v(LOGGER,"ImageBitmap Ht>>>>>>"+downloadableImageView.getTag()+ "this>>>>"+this+""+tempBitmap.getHeight());
downloadableImageView.setImageBitmap(tempBitmap);
}else{
Log.v(LOGGER, "else to download Tag is" + downloadableImageView.getTag()+"this>>>>>"+this);//Works till this point
final Bitmap tempBitmap1 = getBitmap(imageUrl);
Log.v(LOGGER, "else to download Tag is " + downloadableImageView.getTag() + "After Download>>>" + tempBitmap1.getWidth() + "this>>>>>" + this);//Issue happens here
mMemoryCache.addBitmapToMemoryCache(imageUrl, tempBitmap1);
Log.v("LOGGER, else to download Tag is "+downloadableImageView.getTag()+"After Cache>>>", "" + downloadableImageView.getTag()+"this>>>>"+this);
if(tempBitmap1!=null){
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.v("LOGGER, else to download Tag is "+downloadableImageView.getTag()+"RunOnUIThread>>>", "" + downloadableImageView.getTag()+"this>>>>"+loader);
downloadableImageView.setImageBitmap(tempBitmap1);
downloadableImageView.requestLayout();
}
});
}
}
}catch(Exception e){
Log.v("ExceptionBitmap",""+e.getMessage());
}
}
public Bitmap getBitmap(String imageUrl){
Bitmap bitmap=null;
try {
Log.v("Within getBitmap ","run");
URL uri = new URL(imageUrl);
HttpURLConnection connection = (HttpURLConnection)uri.openConnection();
connection.setInstanceFollowRedirects(true);
//bitmap = BitmapFactory.decodeStream(connection.getInputStream());
bitmap = decodeSampledBitmapFromInputStream(connection.getInputStream(), mRequiredWidth, mRequiredHeight);
} catch (Exception e) {
Log.v("ExceptionLoad",""+e.getMessage());
}
return bitmap;
}
}
public Bitmap decodeSampledBitmapFromInputStream(InputStream in
, int reqWidth, int reqHeight) {
InputStream copyiInputStream1 = null;
InputStream copyiInputStream2 = null;
try {
byte[] data = InputStreamTOByte(in);
copyiInputStream1 = byteTOInputStream(data);
copyiInputStream2 = byteTOInputStream(data);
} catch (Exception e) {
e.printStackTrace();
}
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(copyiInputStream1, null, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(copyiInputStream2, null, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public InputStream byteTOInputStream(byte[] in) throws Exception{
ByteArrayInputStream is = new ByteArrayInputStream(in);
return is;
}
public byte[] InputStreamTOByte(InputStream in) throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] data = new byte[1024*16];
int count = -1;
while((count = in.read(data,0,1024*16)) != -1)
outStream.write(data, 0, count);
data = null;
return outStream.toByteArray();
}
class BitmapUpdater implements Runnable
{
Bitmap bitmap;
ImageView imageView;
public BitmapUpdater(Bitmap bitmap, ImageView imageView){
bitmap=bitmap;
imageView =imageView;
}
public void run()
{
// Show bitmap on UI
if(bitmap!=null){
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
else
imageView.setImageResource(R.drawable.account_photo_book_detail2);
}
}
}
我附上了日志供参考,请帮助解决这个问题
Image Tag(0,1)--> I applied Tag for ImageView to sort out the Image View instance
04-06 17:05:57.662 20053-20053/com。xxx。xxxxmobileapp V/ImageLoader﹕ 在ImageDownloader内https://lh6.googleusercontent.com/-8HO-4vIFnlw/URquZnsFgtI/AAAAAAAAAbs/WT8jViTF7vw/s1024/Antelope%2520Hallway.jpgthis
04-06 17:05:57.664 20053-20130/com。xxx。xxxxmobileapp V/ImageLoader﹕ 下载标签is0(imageViewObjectTag)的其他方法
04-06 17:05:57.666 20053-20053/com.xxx.xxxxmobileappV/ImageLoader︰ImageDownloader内https://lh5.googleusercontent.com/-7qZeDtRKFKc/URquWZT1gOI/AAAAAAAAAbs/hqWgteyNXsg/s1024/Another%2520Rockaway%2520Sunset.jpgthis
20053-20130/com.xxx.xxxxmobileappV/ImageLoader︰运行0(ImageViewObjectTag)this
其他要下载的标签是1
下载后要下载的标签为0(imageViewObjectTag)
到目前为止一切都好
下载后要下载的标签为0(imageViewObjectTag)
是的,最后我通过我的朋友阿伦库玛解决了这个问题
对他的赞誉:)
我尝试了两件事,
1)要找出问题是列表视图或执行器服务实现。为了找出答案,我将列表视图替换为线性布局并添加为成功工作的视图,这证实问题是列表视图而不是执行器服务实现。
2)为什么图像在第一个图像中被更新的真正问题是因为视图ID(ImageView.getID())是相同的,
我设置了ID而不是设置标记,并将ID传递给image loader类,然后通过findViewById(SetID)检索图像,这很有效
我正在添加一些代码,这将是有益的
final ImageView imageView = holder.jobImageView;
holder.jobImageView.setId(position);
loader.loadImage(object.getlargeImageUrl(),holder.jobImageView,position);
final Bitmap tempBitmap1 = getBitmap(imageUrl);
Log.v(LOGGER, "else to download Tag is " +imageViewId + "After Download>>>" + tempBitmap1.getWidth() + "this>>>>>" + this);
mMemoryCache.addBitmapToMemoryCache(imageUrl, tempBitmap1);
downloadableImageView = (ImageView)activity.findViewById(imageViewId);
Log.v("LOGGER, else to download Tag is "+downloadableImageView.getTag()+"After Cache>>>", "" + downloadableImageView.getTag()+"this>>>>"+this);
if(tempBitmap1!=null){
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.v("LOGGER, else to download Tag is " + downloadableImageView.getTag() + "RunOnUIThread>>>", "" + downloadableImageView.getTag() + "this>>>>" + loader);
downloadableImageView.setImageBitmap(tempBitmap1);
//downloadableImageView.requestLayout();
}
});
}
我认为这是一个回收问题,问题是在下载完成后,初始的ImageView
,可能代表列表中的另一个位置。您可以看到,这个问题是在调用getBitmap(imageUrl)
之后发生的,但从理论上讲,它也可能更早发生。我不确定您的代码中是否使用了BitmapUpdater
,但乍一看,它与您的情况无关。
因此,为了解决这个问题,您需要实现一种机制,以避免使用“旧”位图更新ImageView
。您可以使用图像视图
的标记
属性来保存需要显示的实际URL。如果图像的标签中的URL与实际用于下载的URL不同,只需缓存图像即可。你可以这样做
public void loadImage (String url,ImageView imageView){
if(imageView != null) imageView.setTag(url);
[...]
}
和
if(tempBitmap1!=null){
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.v("LOGGER, else to download Tag is " + downloadableImageView.getTag()+"RunOnUIThread>>>", "" + downloadableImageView.getTag()+"this>>>>"+loader);
if(downloadableImageView.getTag().equals(imageUrl) {
downloadableImageView.setImageBitmap(tempBitmap1);
}
else Log.v(LOGGER, "the image no longer wants this URL, ignoring");
//downloadableImageView.requestLayout();
}
});
}
此外,我建议避免使用可下载的ImageView。requestLayout()
因为它会导致整个布局被测量,在你的情况下,它是不需要的。
为什么不使用Glide库下载图像?
它只在一行中完成所有事情。
这是它的语法
Glide.with(context).load(URL).into(Imageview);
我用python scrapy编写了一个脚本,从一个网站下载一些图片。当我运行我的脚本时,我可以在控制台中看到图像的链接(它们都是格式)。然而,当我打开下载完成时应该保存图像的文件夹时,我什么也没有看到。我犯错的地方? 这是我的蜘蛛(我正在从Sublime文本编辑器运行): 这是我在中为要保存的图像定义的内容: 为了让事情更清楚: 我希望保存图像的文件夹名为,我已将其放在项目下的文件夹中。 文件夹
我试图下载一个图像从一个URL与Python使用请求和Shutil库。我的代码如下: 这段代码适用于我尝试过的大多数其他图像URL(例如:https://tinyjpg.com/images/social/website.jpg)但是,对于代码中的图像url,创建了一个1kb的文件,其中有一个错误:“看起来我们不支持此文件格式。” 我也尝试过: 可以使用Seleniumwire执行此操作-我使用的
当我想更新JavaFX中的时,出现了一个问题。 调试很混乱,因为我找不到异常的原因。我在网上搜索了一下,但没有找到对我有用的东西。希望有人能帮我解决这个问题。
问题内容: 在我的应用程序上,我使用通用的图像下载器BaseImageDownloader类同步加载画廊的内容。对于来自Imageloader.getInstance()。loadImage异步函数的相同内容,它不会给出任何安全异常并按原样加载图像,但是当我尝试使用BaseImageDownloader同步下载它(而且Imageloader.getInstance()。loadImage()相同)
我有一个表,我想用另一个表中的值更新该表,我正在使用以下代码: 尽管事实上,表。id是tableA的主键,我不断得到以下错误: 错误代码:1175。您使用的是安全更新模式,并且您试图更新一个没有使用键列禁用安全模式的表,请在“首选项”中切换该选项- 我做错了什么?
本文向大家介绍Android ListView实现上拉加载更多和下拉刷新功能,包括了Android ListView实现上拉加载更多和下拉刷新功能的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家介绍了Android ListView下拉刷新功能的实现方法和功能,供大家参考,具体内容如下 1、ListView优化方式 界面缓存:ViewHolder+convertView 分页加载:上拉刷新