Creating Separate Modules for Debug And Release

When it comes to debugging tools and libraries for Android such as Stetho or Chuck or the Jake Wharton’s great Leak Canary, there’re almost separate modules for debug and release builds. For example, when you add Leak Canary in your app, you will be adding dependencies like this:

  debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5.4'
  releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'

Please note that there are two separate modules or AARs for debug and release. Its a common practice to call release variants for debugging and inspection tools as NO OP or No Operations. The purpose of this no-op modules is to do absolutely nothing in the code. Its just an empty wrapper of the debug module to avoid the compile time errors such as Unresolved method name or so.



Few days ago, I was working on a debugging tool plugin for Hyperion called as DBFlow Manager Hyperion plugin. I didn’t know about no-op yet and I simply created a module which did all the work for the DBFlow databases inspection and played very well with Hyperion. I added it in the app using debugImplementation and everything was great until I made a release APK of the app.

I was unable to compile a release APK now. The error I was getting was Unresolved object: DBFlowManager_Hyperion_Constants. You can follow the whole issue (fixed and closed) at here. Apparently, the app was using DBFlowManager_Hyperion_Constants in the code and this class was only available for debug builds as we only included the plugin for debugging. But, since code was using a reference, so release APK couldn’t find the class reference and it failed.

After a simple google search, I managed to learn about how it all works. I created another no-op module. All you have to do is add empty classes and methods and simply compile it. Now when release apk will be compiled, it will find all the references but code will do nothing at all. It will be just for a placeholder purpose.

For example, the DBFlowManagerPlugin class in the debug module looks like this:

public class DBFlowManagerPlugin extends Plugin {

    @Nullable
    @Override
    public PluginModule createPluginModule() {
        return new DBFlowManagerModule();               // This is the functionality class
    }
}

While this same class in release and no-op module is empty and looks like this:

public class DBFlowManagerPlugin {

    //@Override
    public Object createPluginModule() {
        return null;                                   // This is returning null. 
    }
}

Note that only class and method names are same. Even method’s return type has been changed to Object. It’s all an empty and nothing-to-do module.

References

https://medium.com/@orhanobut/no-op-versions-for-dev-tools-b0a865934398

https://xrubio.com/2016/10/disabling-removing-code-on-release-builds/


If you liked this article, you can read my new articles below:


profile card
Wajahat Karim
🌍 Making the world a better place, one app at a time.
🔥 Google Developer Expert (GDE) in Android . 📱 Professional Android Developer with ~10 years experience. 💻 Creator of various Open Source libraries on Android . 📝 Author of two technical books and 100+ articles on Android. 🎤 A passionate Public Speaker giving talks all over the world.
Author's picture

Wajahat Karim

🔥 Google Dev Expert (GDE) in Android .
📱 Android Dev. 💻 Open Source Contributor . 📝 Technical Writer . 🎤 Public Speaker

Senior Android Developer

Karachi, Pakistan