Android: Universal Image Loader - Add new image to cache - android

I am successfully integrate Universal Imageloader in my Gallery App to show the images from the phone storage
But new images (captured from the camera /processed images) stored in the app's specified folder doesn't appear in the gallery. even the application restarted.
May be due to this error
W/ImageLoader: Try to initialize ImageLoader which had already been initialized before. To re-init ImageLoader with new configuration call ImageLoader.destroy() at first.
I think add the details of new image to the cache will resolve the problem. but don't know how . please help
code : Activity Extends Application
DisplayImageOptions defaultDisplayImageOptions = new DisplayImageOptions.Builder() //
.considerExifParams(true)
.resetViewBeforeLoading(true)
.showImageOnLoading(R.drawable.nophotos)
.showImageOnFail(R.drawable.nophotos)
.delayBeforeLoading(0)
.build(); //
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
getApplicationContext())
.defaultDisplayImageOptions(defaultDisplayImageOptions)
.memoryCacheExtraOptions(480, 800).threadPoolSize(5)
.build();
ImageLoader.getInstance().init(config);
load all album
PhoneMediaControl mediaControl = new PhoneMediaControl();
mediaControl.setLoadalbumphoto(new loadAlbumPhoto() {
#Override
public void loadPhoto(ArrayList<AlbumEntry> albumsSorted_) {
albumsSorted = new ArrayList<PhoneMediaControl.AlbumEntry>(albumsSorted_);
if (mView != null && mView.getEmptyView() == null) {
mView.setEmptyView(null);
}
if (listAdapter != null) {
listAdapter.notifyDataSetChanged();
}
}
});
mediaControl.loadGalleryPhotosAlbums(mContext, 0);
is there any way to add new processed image to the cache or already initiated imageloader

You just have to load the your image with universal image loader it will automatically cache it.
Loading
ImageLoader imageLoader = ImageLoader.getInstance();
Uri uri = Uri.fromFile(new File("/DCIM/Camera/1470634175974.jpg"));
imageLoader.loadImage(uri.toString(), new SimpleImageLoadingListener() {
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Do whatever you want with Bitmap
}
});
UNIVERSAL IMAGE LOADER ACCEPTED URI schemes
"file:///mnt/sdcard/image.png" // from SD card
"file:///mnt/sdcard/video.mp4" // from SD card (video thumbnail)
"content://media/external/images/media/13" // from content provider
"content://media/external/video/media/13" // from content provider (video thumbnail)
"assets://image.png" // from assets
"drawable://" + R.drawable.img // from drawables (non-9patch images)

Initialize your UniversalImageLoader instance only once inside onCreate() of your Application class, not inside each Activity or elsewhere.

I found this will reslove the problem using the function loadImageSync();
ImageLoader.getInstance().loadImageSync(filepath);

Related

Cache duplicate Universal ImageLoader and Picasso

Use two biblotecas in my application, Universal Image Loader and another that uses the library picasso,
the picasso library, records the image in the cache /cache/picasso-cache/ and the names are generated with the MD5 URL.
To separate the cache Universal Image Loader, I write to /cache/LazyLoad/ and names generated with the item ID.
My code of configuration Universal Image Loader
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.resetViewBeforeLoading(true)
.cacheOnDisk(true)
.cacheInMemory(true)
.imageScaleType(ImageScaleType.EXACTLY)
.displayer(new FadeInBitmapDisplayer(300))
.build();
ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(getApplicationContext());
config.defaultDisplayImageOptions(defaultOptions);
config.memoryCache(new WeakMemoryCache());
config.threadPriority(Thread.NORM_PRIORITY - 2);
config.denyCacheImageMultipleSizesInMemory();
config.tasksProcessingOrder(QueueProcessingType.LIFO);
config.writeDebugLogs(); // for debug
FileNameGenerator fileNameGenerator = new FileNameGenerator() {
#Override
public String generate(String imageUri) {
String fileName = imageUri.substring(imageUri.lastIndexOf('/')+1, imageUri.length());
String fileNameWithoutExtension = fileName.substring(0, fileName.lastIndexOf('.'));
return fileNameWithoutExtension;
}
};
String pathCache = Globais.getCacheDirImageLazyLoad(mContext); //returns StorageUtils.getCacheDirectory(context, false).getAbsolutePath() + "/lazyload";
File f = new File(pathCache);
if (!f.exists())
f.mkdirs();
DiskCache diskCache = new UnlimitedDiskCache(f, null, fileNameGenerator);
config.diskCache(diskCache);
config.diskCacheFileNameGenerator(fileNameGenerator);
ImageLoader.getInstance().init(config.build());
Problem that after I started using the component that uses the picasso, began to double the cache, ALL images that use the Universal Image Loader, also appear in Picasso's cache.
How can I fix this ???
Anyone have any idea?

Image flickering in imageView when list is scrolled or new image is downloaded in new row

I have gone through many questions similar to mine of images flickering problem.
I am not able to correct it. Being a beginner,I am not able to understand what to do.
Here is my code.. where I set thumbnail for a image.
private void setThumbnail(final ContentResolver contentResolver, final ViewHolder aHolder,
final Uri uri) {
new AsyncTask<String, Void, Bitmap>() {
#Override
protected Bitmap doInBackground(String... params) {
Bitmap result = mBitmapCache.get(uri.toString());
if (result == null)
return getThumbnail(contentResolver, uri);
else
return result;
}
#Override
protected void onPostExecute(Bitmap result) {
if (uri != null && result != null) {
// Log.d(TAG, "setThumbnail result not null");
// Log.d(TAG, "uri= "+uri);
// Log.d(TAG, "aHolder.mMediaUri= "+aHolder.mMediaUri);
mBitmapCache.put(uri.toString(), result);
// confirm the holder is still paired to this uri
if (!uri.equals(aHolder.mMediaUri)) {
return;
}
// set the thumbnail
ImageLoader imageLoader=ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(getContext()));
DisplayImageOptions options = new DisplayImageOptions.Builder()
// .showImageForEmptyUri(R.drawable.ic_empty)
// .showImageOnFail(R.drawable.ic_error)
.resetViewBeforeLoading(true).cacheOnDisk(true)
.imageScaleType(ImageScaleType.EXACTLY)
.bitmapConfig(Bitmap.Config.RGB_565).considerExifParams(true)
.cacheInMemory(true)
.displayer(new FadeInBitmapDisplayer(300)).build();
imageLoader.displayImage(uri.toString(), aHolder.mMediaThumbnail, options);
// aHolder.mMediaThumbnail.setImageBitmap(result);
} else {
// Log.d(TAG, "setThumbnail result null");
}
}
}.execute();
}
In ListView view is added when it is required (See https://stackoverflow.com/a/14108676/2274724). So your item will create when you call notifyDataSetChange() or scroll your list.
So whenever your view is created your image will load again from cache which results into flickering. There is a solution :
First Load image in background thread (Either from network or assets) then create a bitmap cache as u did but instead of getting image using AsyncTask get Image directly if it exist in bitmap cache (But this is again not a good way because it will stop flickering but list scroll will not be smooth when size is large).
I will Suggest use UniversalImageLoader. They implemented memory cache in much better way.
private void setThumbnail(final ContentResolver contentResolver, final ViewHolder aHolder,
final Uri uri) {
ImageLoader.getInstance().displayImage(
uri.toString(),
aHolder.mMediaThumbnail, getDisplayOption());
}
// Add or remove option according to your requirement
private DisplayImageOptions getDisplayOption() {
return new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.ic_launcher)
.showImageOnLoading(R.drawable.ic_launcher)
.showImageOnFail(R.drawable.ic_launcher).cacheInMemory(true)
.cacheOnDisk(true).resetViewBeforeLoading(true)
.displayer(new RoundedBitmapDisplayer(22))
.imageScaleType(ImageScaleType.IN_SAMPLE_INT)
.bitmapConfig(Bitmap.Config.RGB_565).build();
}
//Put it in your Application file and call it just once.
private void initImageLoader() {
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
getApplicationContext())
.threadPriority(Thread.NORM_PRIORITY - 2)
.denyCacheImageMultipleSizesInMemory()
.diskCacheFileNameGenerator(new Md5FileNameGenerator())
.tasksProcessingOrder(QueueProcessingType.LIFO)
.defaultDisplayImageOptions(getDisplayOption()).build();
// Initialize ImageLoader with configuration.
ImageLoader.getInstance().init(config);
}
Before I was using:
AssetManager
InputStream
BitmapFactory
All of this to get a Bitmap
And finally use imageView.setImageBitmap(bitmap)
Nowadays we have libraries that help loading and caching images.
I have used Picasso for loading images from the web.
But Picasso is available for assets too!
Here is a Kotlin example:
val picassoPrefix = "file:///android_asset"
Picasso.get().load("$picassoPrefix/$assetsPath/$fileName")
.placeholder(R.mipmap.ic_launcher_round)
.into(imageView)
Note:
We can use the fetch method for preloading too.
In my case I don't think it's necessary, since the placeholder is displayed for the first time, and for the next times, the images are displayed immediately without flickering.

does ParseImageView cache ParseFile

Does ParseImageView cache ParseFile's in Android. If it caches parseFile, How can i find the path of those files in my android device.
ParseImageView imageView = (ParseImageView) findViewById(android.R.id.icon);
// The placeholder will be used before and during the fetch, to be replaced by the fetched image
// data.
imageView.setPlaceholder(getResources().getDrawable(R.drawable.placeholder));
imageView.setParseFile(file);
imageView.loadInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
Log.i("ParseImageView",
"Fetched! Data length: " + data.length + ", or exception: " + e.getMessage());
}
});
Looks like #suresh kumar is dead right, so this question is settled with "no", but having run into this trouble I wanted to drop some code in here to get around it.
I use Universal Image Loader for URL image loading, and it supports a lot of configuration options for caching and display. Set it up in your Application class with (at time of writing):
//Create image options.
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.button_default)
.cacheInMemory(true)
.cacheOnDisc(true)
.build();
//Create a config with those options.
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.defaultDisplayImageOptions(options)
.build();
ImageLoader.getInstance().init(config);
And then use it with Parse where you'd like to load and cache your image:
ParseImageView itemImage = (ParseImageView) v.findViewById(R.id.iv_item);
ParseFile photoFile = item.getParseFile("picture");
if (photoFile != null) {
//Get singleton instance of ImageLoader
ImageLoader imageLoader = ImageLoader.getInstance();
//Load the image from the url into the ImageView.
imageLoader.displayImage(photoFile.getUrl(), itemImage);
}
Hope that helps.
ParseImageView doesn't cache ParseFile, It is only used to display the image file stored in Parse.com. See this
and this

Universal Image Loader loads slower

I'm writing a custom gallery using UIL library and for testing the performance, I've modified ImagePagerActivity(of example code) to load images from sdcard. Everything works fine but loading is way too slow, sometimes it even takes 5 seconds to load a single image. However if I use in-built gallery, its way faster and loads more images in milliseconds. Here is the snippet of modified onCreate
File file = new File(Environment.getExternalStorageDirectory(), "dcim/100MEDIA/");
File[] images = file.listFiles(new FilenameFilter() {
#Override
public boolean accept(File dir, String filename) {
return filename.toLowerCase(Locale.US).endsWith(".jpg");
}
});
String[] imageUrls = new String[images.length];
for (int a = 0; a < imageUrls.length; a++)
imageUrls[a] = "file://" + images[a].getAbsolutePath();
options = new DisplayImageOptions.Builder().showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error).resetViewBeforeLoading(true).cacheOnDisc(true)
.cacheInMemory(true).imageScaleType(ImageScaleType.EXACTLY).bitmapConfig(Bitmap.Config.RGB_565)
.displayer(new FadeInBitmapDisplayer(300)).build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
.defaultDisplayImageOptions(options).discCacheExtraOptions(800, 800, CompressFormat.PNG, 0, null)
.build();
ImageLoader.getInstance().init(config);
and little modified ImagePagerAdapter
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
spinner.setVisibility(View.GONE);
Toast.makeText(ImagePagerActivity.this, loadedImage.getWidth() + " x " + loadedImage.getHeight(),
Toast.LENGTH_SHORT).show();
}
Usually common image dimension is 2592x1552
UIL 1.8.6
Android version : 4.0.3
Others are just same as example code
What does your ImageLoaderConfiguration look like? What threadPriority do you set it? Also, ImageScaleType.EXACTLY creates another bitmap so this will add load time. For my ImageLoaderConfiguration I have threadPriority set to Thread.MAX_PRIORITY and threadPoolSize set to 5:
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
getApplicationContext()).threadPriority(Thread.MAX_PRIORITY)
.memoryCacheSize(memoryCacheSize)
.memoryCache(new WeakMemoryCache())
.denyCacheImageMultipleSizesInMemory().threadPoolSize(5)
.discCacheFileNameGenerator(new MyFileNameGenerator())
.tasksProcessingOrder(QueueProcessingType.LIFO)// .enableLogging()
.build();

How can i just download image with universal-image-loader

as far as I know, universal-image-loader provide 2 kinds of methods to display images. imageLoader.loadImage and imageLoader.displayImage. But those 2 methods must bind to UI element to display. Can I just download files for cache in a thread (for future display). I don't need to display those image right now.
You can still use UIL. Based on the displayOptions used below the images would be cached.
Refer here - https://github.com/nostra13/Android-Universal-Image-Loader
// Load image, decode it to Bitmap and return Bitmap to callback
imageLoader.loadImage(imageUri, displayOptions, new SimpleImageLoadingListener() {
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Do whatever you want with Bitmap
}
});
Can I just download files for cache in a thread (for future display).
I don't need to display those image right now.
You can download files using Executor or creating a thread. You don't need to use universal imageloader.
http://developer.android.com/reference/java/util/concurrent/Executor.html.
You can also use a DownloadManager and save the file in sdcard. You can retrieve the same for later use.
http://oodlestechnologies.com/blogs/Downloading-and-Retrieving-Files-on-SD-card-in-Android-using-Android-SDK-in-Eclipse
To cache bitmaps you can write the images to a folder in sdcard.
Caching bitmaps
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html.
You cache bitmaps in memory or disk. The link has details regarding the topic.
You basically use UIL ofr displaying images in listview or grdiview. To use UIL in listview or gridview you can do as below.
https://github.com/nostra13/Android-Universal-Image-Loader. It is based on Lazy List(works on same principle). But it has lot of other configurations. You can display a error image if downlaod failed. Can display images with rounded corners. Can cache on disc or memory. Can compress image.
In your custom adapter constructor
File cacheDir = StorageUtils.getOwnCacheDirectory(a, "your folder");
// Get singletone instance of ImageLoader
imageLoader = ImageLoader.getInstance();
// Create configuration for ImageLoader (all options are optional)
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(a)
// You can pass your own memory cache implementation
.discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
.discCacheFileNameGenerator(new HashCodeFileNameGenerator())
.enableLogging()
.build();
// Initialize ImageLoader with created configuration. Do it once.
imageLoader.init(config);
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.stub_id)//display stub image
.cacheInMemory()
.cacheOnDisc()
.displayer(new RoundedBitmapDisplayer(20))
.build();
In your getView()
ImageView image=(ImageView)vi.findViewById(R.id.imageview);
imageLoader.displayImage(imageurl, image,options);//provide imageurl, imageview and options
You can configure with other options to suit your needs.
Along with lazy loading/Universal Image Loader you can view holder for smooth scrolling and performance. http://developer.android.com/training/improving-layouts/smooth-scrolling.html.
Theres loadImage(String uri, ImageLoadingListener listener), I think you can call it with null for the listener if you don't need one.
Adding to #Robin Srivastava's answer:
You must also instantiate the ImageLoader context, for example:
imageLoader = ImageLoader.getInstance(); before you can use the loadImage method. The displayOptions parameter is also optional so you can exclude that if need be.
Using UIL,we can save the image when the image is fully loaded.
using ImageLoading Listener when loading is completed the listener has a method called onLoadingComplete() we can get Bitmap of the image and we can store this Bitmap using the below method saveImage()
Bitmap imageBitmap=null;
ImageLoader.getInstance().displayImage(String.valueOf(mediaPath), imageView, options, new ImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
progressBar.setVisibility(View.VISIBLE);
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
String message = null;
switch (failReason.getType()) {
case UNKNOWN:
message = "Unknown error";
break;
case IO_ERROR:
message = "I/O error";
break;
case NETWORK_DENIED:
message = "Network Denied";
break;
case OUT_OF_MEMORY:
message = "Out of memory";
break;
case DECODING_ERROR:
message = "decoding error";
break;
}
Toast.makeText(FullScreenActivity.this, message, Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
//we can get imageBitmap here when loading is completed
imageBitmap=loadedImage;
progressBar.setVisibility(View.GONE);
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
}
});
Use this method to save the file in your local storage
public void saveImage(){
if(imageBitmap!=null){
File dir = new File( Environment.getExternalStorageDirectory().getAbsolutePath() + “/Images/");
if (!dir.exists()) {
if (dir.mkdirs()) {
Log.i(TAG, "Directory created");
}
}
//put your image file name here
File mypath=new File(dir,"yourImageName.png");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
if(imageBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)){
showToast("Successfully downloaded");
}
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Toast toast=null;
private void showToast(String message) {
if (toast != null) toast.cancel();
toast = Toast.makeText(FullScreenActivity.this, message, Toast.LENGTH_SHORT);
toast.show();
}

Categories

Resources