That’s an addition to my previous story How to move password to system environment variables and load it with Gradle — read it at first to grasp the context.

In your build.gradle:

signingConfigs {
release {
// Example of the MY_KEYSTORE value for Windows: D:/workspace/my_release_keystore.jks
def keystore = System.getenv("MY_KEYSTORE")
def kAlias = System.getenv("MY_KEYSTORE_ALIAS")
def kPass = System.getenv("MY_KEYSTORE_PASS")
storeFile file("$keystore")
storePassword "$kPass"
keyAlias = "$kAlias"
keyPassword "$kPass"
debug {
storeFile file("../debug.keystore")

That eliminates the need of storing the keystore and password in the repository and gives more flexibility in build process setup.

Moving the password away from your codebase is not just a security but a good first step to adapt the project to CI.

1. Add the system environment variable

Note: if you use Windows — don’t forget to restart the IDE after adding the variable to the system environment variables.

My env var

2. Add buildConfigField to build.gradle of your module.

When the variable is set you need to add buildConfigField in your Gradle build type:

buildTypes {
stage {
def keystorePass = System.getenv("KEYSTORE_PASS")
buildConfigField 'String', 'keystorePass', "\"$keystorePass\""
dev {
def keystorePass = System.getenv("KEYSTORE_PASS") …

I’ve already written about how to use ViewModel, Retrofit and Coroutines here and here. This tiny note is an extension but can be consumed without preliminary reading.

The problem

Imagine that you have a network call that is executed on some UI event: button press, broadcast event etc. It worked pretty well until somebody invoked that UI event too fast… Most probably the part of the data will be lost. That’s because you need a queue.


All you need is Channel, right!

private val eventsChannel = Channel<Event>(capacity = 100)

Event is my custom class. Just plain model.

This code should be executed…

Since Retrofit supports Kotlin Coroutines it’s so convenient to use it with suspend functions and viewModelScope.

The problem

But the real pain can be to properly cancel Retrofit operations (e.g. when network connection disappears). I mean the case when user started some network operation with Retrofit and then connection broke. By default you’ll get some connection exception that cannot be handled (at least in my case).

I have authentication interceptor inside Koin network module and it throws an exception on the last line chain.proceed(request) when timeout is over after connection brake. I tried to wrap that part of the code in try-catch…

As you know ViewModel should not use Context. Yes, there is AndroidViewModel but if you want to keep ViewModel as flat as possible (or if you use Koin as me) — welcome under the hood.

The problem

We need to observe connectivity changes and propagate them to ViewModel. Inside ViewModel there are several use cases when we need to check connectivity state:

  1. Before performing a network request.
  2. Cancel Retrofit calls on connectivity brake.


All you need is ConnectionLiveData!

class ConnectionLiveData(private val context: Context) : LiveData<Boolean>() { private val networkReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { postValue(context.isConnected)…

Important note: Android does not support JKS keystores. But all Android versions support PKCS12 and BKS. To generate PKCS12 private key is needed which I didn’t have so I had to use BKS.

There is an informative article that describes how to generate BKS file. Refer to step 2 in that article.

Then place keystore.bks to res/raw folder.

Add the next code where builder is OkHttpClient.Builder instance.

// SSL certificate configuration
val trustStore = KeyStore.getInstance("BKS")
androidContext().resources.openRawResource(R.raw.keystore).use {
trustStore.load(it, KEYSTORE_PASS.toCharArray())
val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).apply {
val sslContext = SSLContext.getInstance("TLS").apply {
init(null, tmf.trustManagers, SecureRandom())
val trustManager = tmf.trustManagers[0] as X509TrustManager
builder.sslSocketFactory(sslContext.socketFactory, trustManager)

That’s all! Happy coding!

First of all, let’s skip the questions — why you need to do this? I assume that you’ve asked this question yourself and colleagues before and manual ordering should be used only as a last resort.


You should use custom serializer.

Gson gson = new GsonBuilder().registerTypeAdapter(YourClass.class, new YourClassSerializer()).create();public class YourClassSerializer implements JsonSerializer<YourClass> {
public JsonElement serialize(YourClass obj, Type type, JsonSerializationContext context) {
JsonObject json = new JsonObject();
json.add(“field1”, context.serialize(obj.field1));
json.add(“field2”, context.serialize(obj.field2));
return json;

Then I use that class as a body for post request:

Call<Result> startSearch(@Body YourClass body);

Hope that helped you. Good luck!

Статья рассчитана на новичков и ее цель, в первую очередь, — объяснить шаги, какие нужно предпринять. За деталями по каждому этапу советую обращаться в гугл или ютуб — там всё есть, поверьте. Я дам полезные ссылки.

Итак, в качестве примера я возьму свой роутер Xiaomi WiFi Mini.

Чтобы поднять FTP сервер и вывести его в сеть, нужно предпринять следующие шаги:

  1. Прошить китайскую девелоперскую прошивку.
  2. Прошить прошивку от padavan.
  3. Настроить FTP и DDNS.

Приступим к делу.

Прошивка на дев

Для начала, необходимо открыть SSH. SSH — это возможность удаленного управления роутером. Если он открыт, то можно с ноутбука подключиться к роутеру…

This publication covers a 0.3.0 release of my open-source project Android Dependency Graph (ADG).

In the latest release I finally(!) addressed performance (or it’s better to say ‘design’) issues that the tool had for 3 years of existence.

Short history reference

The first version of ADG was developed in 2016. The purpose of the tool is to build a dependency graph of classes using just an APK file (a file for distributing Android applications).

The steps to show a graph are the next:

  1. Decompile .apk file to Smali code.
  2. Analyze the Smali code and build .js file with dependencies.
  3. Display the graph at…

Image source:

How often do you think about the architecture of your project? I believe that every class should be written with the architecture in mind. And it seems that people at Microsoft think the same way. But still, there is a gap in the documentation to Microsoft Bot Framework. In order to grasp how to write code using this framework correctly, you should dig into their samples.

Looking through the samples I understood that the Microsoft guys made their framework very flexible — we just need to learn how to use it. …

Alexander Zaitsev

Android (Kotlin / Java)

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store