I am showing list of images from server. Images may have different size and resolutions. I have observed that Image is taking time to load in Imageview.
Even in good internet network, its taking much time.
if (imageView != null && imageUri != null) {
RequestOptions options = new RequestOptions();
options.error(R.drawable.ic_payment_failed);
options.format(DecodeFormat.PREFER_RGB_565);
options.override(500, 500);
imageView.setImageUri(imageUri);
Glide.with(context).asBitmap()
.apply(options)
.load(imageUri)
.into(imageView.getProfilePic());
}
}
I have tried lot many glide methods to improve loading speed, but no result.
And if try to load large image i.e 4-5 MB, Glide throwing Unable to load resource exception. To deal with this type of issue i have used transformation. But still no result.
I want image should display fast.
you can Use GlideApp for new version glide.
you must create a java class with this name MyAppGlideModule in your project. and make class like below code.
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;
#GlideModule
public final class MyAppGlideModule extends AppGlideModule {
}
and you can also use OKHttp for glide with add this dependence in your Gradle.
implementation "com.github.bumptech.glide:okhttp3-integration:4.8.0"
and replace that class
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;
#GlideModule
public final class MyAppGlideModule extends AppGlideModule {
#Override
public void registerComponents(Context context, Glide glide, Registry registry) {
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(15, TimeUnit.SECONDS)
.connectTimeout(15, TimeUnit.SECONDS)
.build();
OkHttpUrlLoader.Factory factory = new OkHttpUrlLoader.Factory(client);
glide.getRegistry().replace(GlideUrl.class, InputStream.class, factory);
}
}
after that Build your project.after you Build project. you can Use GlideApp instead Glide.like this
GlideApp.with(context)
.load(myUrl)
.placeholder(placeholder)
.into(yourTarget);
you can use the latest version of glide.
implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
Related
I have this line of code on my android studio app
if (obj.getPhotoUrl() != null) {
ImageUtil.loadImage(GlideApp.with(context), obj.getPhotoUrl(), avatarImageView);
}
But it shows error "
Required type:
GlideRequests
Provided:
com.devlomi.fireapp.utils.glide.GlideRequests "
This is my MyAppGLideModule class
#GlideModule
public class MyAppGlideModule extends AppGlideModule {
#Override
public void registerComponents(Context context, Glide glide, Registry registry) {
registry.prepend(String.class, ByteBuffer.class, new Base64ModelLoaderFactory());
}
}
How to correct the error I want to load images using the Glide
if all you want is to load an image using Glide into an ImageView, then you don't need to extend any class inorder to use Glide.
you can just load the the image using its Uri with this line of code :
Glide.with(context).load(obj.getPhotoUrl()).into(avatarImageView);
if that's not what you meant in your question, can you explain more ?
With Glide Library it becomes a little easy to load the images from a url into an ImageView
And for this we use
Glide.with(getApplicationContext).load.(obj.getPhotoUrl()).into(imageView)
java Code for load image fom URL
ImageView img = (ImageView) findViewById(R.id.imageView);
Glide.with(MainActivity.this)
.load("https://yildirim.bel.tr/uploads/haberler/4509c5f0-7498-
4932-85d4-767e48408299image.jpeg")
.into(img);
manifest
<uses-permission android:name="com.googleandroid.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Gradle
implementation 'com.github.bumptech.glide:glide:3.8.0'
First create a class like that:
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;
// new since Glide v4
#GlideModule
public final class MyAppGlideModule extends AppGlideModule {
// leave empty for now
}
Then call the Glide as:
GlideApp.with(context)
.load("https://yildirim.bel.tr/uploads/haberler/4509c5f0-7498-
4932-85d4-767e48408299image.jpeg")
.override(300, 200)
.into(img);
Try this
RequestOptions options = new RequestOptions()
.centerCrop()
.placeholder(R.mipmap.ic_launcher_round)
.error(R.mipmap.ic_launcher_round);
Glide.with(this).load(image_url).apply(options).into(imageView);
When I use Glide to put and image inside an ImageView and then I "zoom in" (with a function that I bound to my ImageView), I see that the image has a low quality.
I already read Glide documentation but I'm not able to solve the problem.
Note: I use Glide inside a ViewPager.
This is what I did following the documentation
Glide
.with(context)
.loadFromMediaStore(uri)
.dontAnimate()
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(imageView);
This is the Manifest.xml
<manifest ...>
<application...>
<meta-data android:name="come.package.glide.MyGlideConfiguration"
android:value="GlideModule"/>
</application>
</manifest >
This is my GlideConfiguration
public class GlideConfiguration implements GlideModule {
#Override
public void applyOptions(Context context, GlideBuilder builder) {
// Apply options to the builder here.
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
}
#Override
public void registerComponents(Context context, Glide glide) {
// register ModelLoaders here.
}
}
I also tried doing just
Glide
.with(context)
.loadFromMediaStore(uri).asBitmap().format(DecodeFormat.ALWAYS_ARGB_8888)
But the quality is always low.
Does anybody see where is my error??
Instead of calling
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
try
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
how to Combine Glide and Stetho to debug image loading system using okhttp3
I did the following
1.Added the dependancies
//stetho
compile 'com.facebook.stetho:stetho:1.3.1'
compile 'com.facebook.stetho:stetho-okhttp3:1.3.1'
//glide
compile 'com.github.bumptech.glide:glide:3.7.0'
// Glide's OkHttp3 Integration
compile 'com.github.bumptech.glide:okhttp3-integration:1.4.0#aar'
//okhttp3
compile 'com.squareup.okhttp3:okhttp:3.2.0'
1.Added the initialization
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
Stetho.initialize(
Stetho.newInitializerBuilder(this)
.enableDumpapp(Stetho.defaultDumperPluginsProvider(this))
.enableWebKitInspector(Stetho.defaultInspectorModulesProvider(this))
.build());
}
}
3.add glide config to use okhttp3
/**
* Created by Arnaud Camus Copied by MOMANI on 2016/04/15.
* http://arnaud-camus.fr/combining-glide-and-stetho-to-easily-debug-your-image-loading-system/
*/
public class StethoOkHttpGlideModule implements GlideModule {
#Override
public void applyOptions(Context context, GlideBuilder builder) { }
#Override
public void registerComponents(Context context, Glide glide) {
okhttp3.OkHttpClient client = new okhttp3.OkHttpClient();
client.networkInterceptors().add(new com.facebook.stetho.okhttp3.StethoInterceptor());
glide.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(client));
}
}
4.added the GlideModule metadata tag in AndroidManifest.xml
<application
android:name=".....">
.....
<meta-data android:name="android.alcode.com.material.utils.glide.StethoOkHttpGlideModule"
android:value="GlideModule" />
</application>
5.Glide loadimg images line
Glide.with(((ViewHolderSmall) holder).imageView.getContext())
.load(post.getImageUrl())
// .diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(((ViewHolderSmall) holder).imageView);
when I open chrome Developer tool Resources Tab works perfectly but network tab doesn't!!!
why? where is my mistake? and is it recommended to use okhttp3 with Glide? and how how to connect it without using okhttp3
any duplication or links would help
Re: is it recommended to use okhttp3 with Glide?
Yes, this is the way to go for OkHttp integration.
Re: why? where is my mistake?
This is likely needed because the built-in GlideModule may be overwriting your intercepted client (there's no defined ordering between GlideModule execution). Consider the following from the wiki:
When overriding default behaviour make sure your custom GlideModule is registered in the manifest and the default one is excluded. Exclusion may mean removing the corresponding metadata from the manifest or using the jar dependency instead of the aar one. -- Overriding default behaviour - Glide Wiki
Based on Conflicting GlideModules - Glide Wiki: remove #aar from the okhttp3-integration dependency, or add to manifest:
<meta-data android:name="com.bumptech.glide.integration.okhttp3.OkHttpGlideModule" tools:node=”remove” />
Also make sure you're not fooled by the cache: .diskCacheStrategy(NONE).skipMemoryCache(true); you can remove this as soon as you see the requests as you expect them to.
OkHttp3 changed the API client.networkInterceptors() is not writable any more:
okhttp3.OkHttpClient client = new okhttp3.OkHttpClient.Builder()
.addNetworkInterceptor(new com.facebook.stetho.okhttp3.StethoInterceptor())
.build();
Re: how how to connect it without using okhttp3
The default (built-in) network integration uses HttpUrlFetcher created by HttpUrlGlideUrlLoader, so in order to integrate with Stetho you'll need to replace those with one that intercepts requests.
'
GlideModule
#Override public void registerComponents(Context context, Glide glide) {
glide.register(GlideUrl.class, InputStream.class, new StethoHttpUrlGlideUrlLoader.Factory());
}
Make sure StethoHttpUrlGlideUrlLoader returns the modified classes and not the built-in ones in build and getResourceFetcher.
Custom Fetcher
Only the structural diff is included here for brevity, it should be clear where these lines go from the context. Full code is available on GitHub:
public class StethoHttpUrlFetcher implements DataFetcher<InputStream> {
private final StethoURLConnectionManager stethoManager;
public StethoHttpUrlFetcher(GlideUrl glideUrl) {
...
this.stethoManager = new StethoURLConnectionManager("Glide");
}
private InputStream loadDataWithRedirects(...) {
...
//urlConnection.setRequestProperty("Accept-Encoding", "gzip"); // don't request, it's wasteful for images
...
stethoManager.preConnect(urlConnection, null);
try {
// Connect explicitly to avoid errors in decoders if connection fails.
urlConnection.connect();
stethoManager.postConnect();
} catch (IOException ex) {
stethoManager.httpExchangeFailed(ex);
throw ex;
}
...
}
private InputStream getStreamForSuccessfulRequest(HttpURLConnection urlConnection) throws IOException {
try {
InputStream responseStream = stethoManager.interpretResponseStream(urlConnection.getInputStream());
if (TextUtils.isEmpty(urlConnection.getContentEncoding())) {
...
stream = ContentLengthInputStream.obtain(responseStream, contentLength);
} else {
...
stream = responseStream;
}
return stream;
} catch (IOException ex) {
stethoManager.httpExchangeFailed(ex);
throw ex;
}
}
#Override public void cleanup() {
...
if (isCancelled) { // otherwise it stays pending indefinitely because the stream is not read
stethoManager.httpExchangeFailed(new IOException("Cancelled"));
}
}
}
Finally it worked
according to Glide Wikis I changed the following
<application
android:name=".....">
.....
<meta-data android:name="android.alcode.com.material.utils.glide.StethoOkHttpGlideModule"
android:value="GlideModule" />
<meta-data android:name="com.bumptech.glide.integration.okhttp3.OkHttpGlideModule" tools:node="remove" />
</application>
and according to #TWiStErRob's Answer I changed the following
public class StethoOkHttpGlideModule implements GlideModule {
#Override
public void applyOptions(Context context, GlideBuilder builder) { }
#Override
public void registerComponents(Context context, Glide glide) {
okhttp3.OkHttpClient client = new okhttp3.OkHttpClient.Builder()
.addNetworkInterceptor(new com.facebook.stetho.okhttp3.StethoInterceptor())
.build();
glide.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(client));
}
}
that's it but some questions about okhttp3 not answered
I have a simple ListActivity that shows images and I inizialize my OkHttpClient for Picasso Builder in the constructor of the ImageAdapter class:
picassoClient = new OkHttpClient();
picassoClient.interceptors().add(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain
.request()
.newBuilder()
.addHeader("Cookie","xyz")
.build();
return chain.proceed(newRequest);
}
});
new Picasso.Builder(context).downloader(new OkHttpDownloader(picassoClient)).build();
then in getView() I use Picasso to load images in ImageView:
Picasso.with(context).load(xyzUrl).fit().centerCrop().into(vImage);
It works well, but on device's rotation i see that heap size sometimes slowly grows, sometimes quickly and sometimes remains stable. Only rarely it drops. Am i leaking memory or is there something wrong in code?
EDIT:
I inserted this code after Picasso's call in the getView()
if (BuildConfig.DEBUG) {
Log.i("HEAP SIZE",
String.valueOf((Runtime.getRuntime().totalMemory() / 1024)
- (Runtime.getRuntime().freeMemory() / 1024)));
}
and I found that the heap size's growth happens in the getView() after loading bitmap into ImageView.
What is wrong?
EDIT 2:
tried to set static ImageAdapter, nothing changes
EDIT 3:
tried with RecyclerView instead of ListView, same behavior: heap size grows continuously while scrolling image list stepping by 30-40 bytes at every onBindViewHolder(). After device's rotation heap size grows sometimes stepping by even 2-3 Mbytes. Rarely it drops.
Why heap size slowly but continuously grows and why am I leaking some cache or some cached bitmaps after device's rotation?
UPDATE:
tried adapter without the code in the constructor (that is without new OkHttpClient and new Picasso.Builder), it works and the heap size now drops well remaining stable. Then, what is the correct way to initialize the client with cookies headers management?
UPSHOT:
finally I created my PicassoInstance class, which creates a unique static Picasso singleton and set it as the Picasso Library's singleton. Then I set it in my adapter constructor
PicassoInstance.setPicassoSingleton(context);
It works well, and it is a correct way I hope.
public class PicassoInstance {
private static Picasso myPicassoInstance = null;
public static void setPicassoSingleton(Context context) {
if (myPicassoInstance == null) {
myPicassoInstance = createMyPicassoInstance(context);
Picasso.setSingletonInstance(myPicassoInstance);
if (BuildConfig.DEBUG) {
Log.i("PICASSO INSTANCE", "CREATED");
}
}
}
private static Picasso createMyPicassoInstance(Context context) {
OkHttpClient myOkHttpClient = new OkHttpClient();
myOkHttpClient.interceptors().add(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("Cookie", "xyz").build();
if (BuildConfig.DEBUG) {
Log.i("ON INTERCEPT", "COOKIE ADDED");
}
return chain.proceed(newRequest);
}
});
return new Picasso.Builder(context).downloader(
new OkHttpDownloader(myOkHttpClient)).build();
}
}
The picasso instance being returned from PicassoBuilder.build() should be a singleton, and when you need to use picasso throughout the app you should be accessing that singleton, instead of Picasso.with... you should be accessing
YourClass.getMyPicassoSingleton().with...
Otherwise you're keeping separate caches, etc for those picasso instances
edit: as I noted below, you can also call
picasso.setSingletonInstance(myPicasso);
right where you invoke the build method above, which would also solve your problem without holding onto the singleton yourself. that is probably a cleaner solution
I cannot close it as too broad, but I'd recommend you took a memory dump and gave it a long hard look in Eclipse Memory Analizer Tool to find which references are still being kept alive and by who.
This is also a great write up on it.
Adapters as fields are leaky. Views contain context which contains views. And fragments are even worse offenders. ListActivities were an API1 tool that should have been deprecated long ago. All very leak prone, but that's the Android way.