In our last Glide tutorial, you've learned the basics of GlideModule
s. They provide an easy access to some fundamental functions of Glide's core. You can quickly modify Glide's behavior by implementing and declaring GlideModule
s. Last week, we've changed the image quality to a higher decode format by utilizing the applyOptions()
method. This week, we'll use the other method, registerComponents()
, to modify Glide's network stack to accept connections and images from self-signed HTTPS servers.
Glide Series Overview
- Integrating Networking Stacks
- Customize Glide with Modules
- Glide Module Example: Accepting Self-Signed HTTPS Certificates
- Glide Module Example: Customize Caching
- Glide Module Example: Optimizing By Loading Images In Custom Sizes
- Dynamically Use Model Loaders
Modifying Glide With GlideModule
Before continuing to read, please make sure you read and understood our previous tutorials on GlideModule
s. We won't go over the basics in this tutorial again. Instead, we jump right to the issue. So make sure you're up-to-date with the fundamentals of GlideModule
s.
You're aware that GlideModule
s offer you two methods to change the behavior. Last week, we've looked at the first method, applyOptions()
. This week, we'll use the other method, registerComponents()
, to set a different network stack. By default, Glide internally uses a customized version of the standard HTTPUrlConnection to download images. Glide also offers integration libraries. All three of them are very strict in their security settings, which is very good. The only downside can be the situation when your images are on a server, which uses HTTPS
, but uses a self-signed certificate. Glide would not load or display the images, since the self-signed certificates are considered a security issue.
Unsafe OkHttpClient
Thus, you'll need to implement your own network stack, which accepts self-signed certificates. Luckily, we've implemented and used an "unsafe" OkHttpClient before. We can just copy and paste the class, since it gives us a regular OkHttpClient
, which we'll need to integrate:
public class UnsafeOkHttpClient {
public static OkHttpClient getUnsafeOkHttpClient() {
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]);
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
OkHttpClient okHttpClient = builder.build();
return okHttpClient;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
The created OkHttpClient
disables all SSL certificate checks.
Integration into Glide
Our advantage is that the OkHttp integration library for Glide does almost the same thing, so we can follow their lead. First, we'll need to declare our customization in the GlideModule
. As you already expected, we'll need to do the adaption in the registerComponents()
method. We can call the .register()
method to exchange some fundamental components of Glide. Glide uses a ModelLoader to link a data model to a concrete data type. In our example, we'll need to create a ModelLoader
, which links an incoming URL, represented by the GlideUrl
class to an InputStream
. Glide needs to be able to create instances of our new ModelLoader
, so we're passing a factory in the .register()
method:
Glide 4.x
@GlideModule
public class UnsafeOkHttpGlideModule extends LibraryGlideModule {
@Override
public void registerComponents(Context context, Glide glide, Registry registry) {
OkHttpClient client = UnsafeOkHttpClient.getUnsafeOkHttpClient();
registry.replace(GlideUrl.class, InputStream.class,
new OkHttpUrlLoader.Factory(client));
}
}
Glide 3.x
public class UnsafeOkHttpGlideModule implements GlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
}
@Override
public void registerComponents(Context context, Glide glide) {
OkHttpClient client = UnsafeOkHttpClient.getUnsafeOkHttpClient();
glide.register(GlideUrl.class, InputStream.class,
new OkHttpUrlLoader.Factory(client));
}
}
The first two parameters of the method are the model class and the linked resource class. The last parameter is the ModelLoaderFactory
. Consequently, we can't set an UnsafeOkHttpClient
instance directly, we'll need to pass a ModelLoaderFactory
, which provides the link between the URL and the input stream using the UnsafeOkHttpClient
. In this case we'll just re-use Glide's OkHttpUrlLoader
class and pass our custom OkHttpClient
object to the constructor.
Glide 3.x: Declaration of Glide Module
Finally, if you're using Glide 3.x, you need to declare the new module in the AndroidManifest.xml
:
<manifest
...
<application>
<meta-data
android:name="io.futurestud.tutorials.glide.glidemodule.UnsafeOkHttpClient"
android:value="GlideModule" />
...
</application>
</manifest>
Outlook
In this tutorial, you've seen a different use case of changing the way Glide works. We've implemented an "unsafe" network stack and integrated it into Glide with the registerComponents()
method of a GlideModule
. But that's just the tip of the iceberg of possible Glide modifications.
Next week, we'll look at another option for a GlideModule
to change Glide's caching behavior.