Prototyping Android Apps Without Server API’s

Vinay Shetty
5 min readApr 25, 2017

--

If you are into app development for any long you may already familiar with the dependency of android apps on server API’s. Most of the apps won’t even starts without connecting to a backend API. Yet it’s very common that the API’s you need to build the app are not available at the time you start coding your app, your clients API’s are bound to be broken during development. Or you want to build a prototype so that you can demo it to the stakeholders before jumping into all the implementation details and you don’t have required API’s! Don’t let all these silly things stop you from developing the app that you always wanted to build. Here are the simple ways to bypass your immediate requirements on backend API’s.

In this article I will discuss three quick ways to prototype android apps without having the real backend API’s which you can implement in a matter of minutes, without writing much boilerplate code so that you can always quickly swap your prototype with actual implementation when available and be assured that it works exactly in the way you expected it to be!

1. Using Local Json Server:

You can make your development machine to work like your app backend in a matter of seconds, achieving this is very easy especially with tools like Json-server. Json-server is a simple open source server which you can run on your local machine that helps for quick prototyping. You can install this tool easily by typing the below command in your terminal

$ npm install -g json-server

This project’s Github repo linked below provides enough information about the things you need to get going with Json server .

This video also provides the necessary details about setting up Json-server. After watching it you should be able to get up and running with Json-server!

Now point your apps base url to your development machines ip along with your API path which will look some thing like below

http://10.42.0.1:3000/contacts

where contacts is the place holder for the API endpoint that you have configured in the Json-server.

Now setup hotspot in your local machine and disable cellular Internet in your device and connect the device to the hotspot you created. You should see the app content getting served from Json-server! Note that if you are executing post call to json server having an id field in your request json body is mandatory.

While there is no code associated with this you can checkout my sample repository at github, and watch it change with the next two examples

2. Using OkHttpNetwork Interceptors:

OkHttp and retrofit are now becoming a standard for network communication in android applications and as with most of the library’s from Square, OkHttp provides great support to add your own extensions. Here we use the interceptors provided with OkHttp library to selectively respond with the self prepared network responses, which help us in prototyping.

It is important to add the interceptor as application interceptor in OkHTTP, if you are not familiar with the difference between application interceptor and network interceptor here is a good wiki on the topic.

@Override
public Response intercept(Chain chain) throws IOException {
final String url = chain.request().url().toString();
switch (url) {
case "http://10.42.0.1:3000/contacts": {
final ResponseBody responseBody = ResponseBody
.create(MediaType.parse("application/json"), readFromFile("contacts_response.json"));
final Response response = new Response
.Builder()
.body(responseBody)
.request(chain.request()).message("OK")
.protocol(Protocol.HTTP_1_1)
.code(200)
.build();
return response;
}
}
return chain.proceed(chain.request());
}

Using this approach we read Json response from a file, which I typically place in assets folder and return as the network response.

public String readFromFile(String fileName) throws IOException {
InputStream inputStream = context.getResources().getAssets().open(fileName);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder jsonString = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
jsonString.append(line);
}
return jsonString.toString();
}

the complete source code is available at following github repo.

3. Prototyping With Network Behaviour

This is my personal favourite of the three, you may hate to prototype an application with the methods described earlier because most of the time you like to see how the loading animation looks like?, what happens when there is variance in network response time? , how your app behaves for failure conditions? the approach described in this section allows you to do all that but it also comes with some extra configurations. be sure that you remove all these configurations before you take it to the production.

With great power comes great responsibility

If you are into instrumentation testing you may be already familiar with the network behaviour delegate that square has provided along with the retrofit. But you know what? If you shamelessly copy the provided mock package in retrofit to your prototyping code and promise your self that you are going to delete that code before you take it into production you can simulate almost every network behaviour such as network delay,network errors variance in network time and even the exceptions!

Here is the code snippet for using MockRetrofit with network delegate which allows you to define error percentage, network delay and variance in network response time.

The MockRetrofit object wraps the retrofit instance inside it and provides us a way to delegate network behaviour using BehaviorDelegate class.

public class MockContactService implements ContactListService {
private Context context;
private final BehaviorDelegate<ContactListService> behaviorDelegate;
private List<Contact> contacts;

public MockContactService(Context context,BehaviorDelegate behaviorDelegate) {
this.context = context;
this.behaviorDelegate = behaviorDelegate;
this.contacts = new ArrayList<>();
}

@Override
public Call<List<Contact>> getContacts() {
try {
final String fromJsonFile = Utils.readFromJsonFile(context, "contacts_response.json");
Type listType = new TypeToken<List<Contact>>(){}.getType();
contacts = new Gson().fromJson(fromJsonFile, listType);
} catch (IOException e) {
e.printStackTrace();
}
return behaviorDelegate.returningResponse(contacts).getContacts();

}
}
@Singleton
@Provides
public MockRetrofit provideMockRetrofit(Retrofit retrofit){
final NetworkBehavior behavior = NetworkBehavior.create();
behavior.setErrorPercent(50);
behavior.setDelay(4, TimeUnit.SECONDS);
behavior.setVariancePercent(10);
final ExecutorService executor = Executors.newSingleThreadExecutor();
final MockRetrofit mockRetrofit = new MockRetrofit.Builder(retrofit).backgroundExecutor(executor).networkBehavior(behavior).build();
return mockRetrofit;
}

Have a look at the number of options that the BehaviorDelegate class provides us to play with the network behaviour!

@Provides
public static ContactListService provideContactListService(MockRetrofit retrofit, Context context){
final BehaviorDelegate<ContactListService> mockContactsServiceBehaviorDelegate = retrofit.create(ContactListService.class);
return new MockContactService(context,mockContactsServiceBehaviorDelegate);
}

We provide the retrofit network interface as we do usually but with a difference that the provided network service is actually provided by a MockRetrofit instance which wraps retofit instance inside it and delegates it’s network behaviour to a BehaviourDelegate that is defined by you.

Complete source code is available at the following github repo.

Thanks for reading this article. Be sure to click ❤ below to recommend this article if you found it helpful. It means a lot to me.

Also, Let’s become friends on Twitter,LinkedIn,GitHub

--

--

Vinay Shetty

Ultimately the product that any writer has to sell is not the subject being written about,but who he or she is!