Testing User Interactions with Espresso

Espresso is a testing framework which provides the facility to write the tests for user interactions and unitary tests. Since the release of its version 2 it is now a part of Android Testing Support Library. The android apps we build at FOSSASIA follow rigorous testing methods. See this simple UI test  in the Phimp.me app using espresso to check if button and bottom navigation are displayed in an activity. You can also find our other tests related to API and databases in the Open Event Android App. In this blog we learn how to add this facility to your app and write a test for a simple app that takes the name of from the user and prints it on the other screen on button click. Adding espresso support Install android support repository if not already present. You do it by following Tools -> Android -> SDK Manager Add the following dependencies to your app’s build.gradle file dependencies {   androidTestCompile 'com.android.support.test:runner:0.5'   androidTestCompile 'com.android.support.test:rules:0.5'   androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' } Specify the test instrumentation runner in default config android {    defaultConfig {        // ....        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"    } } Before we begin with writing our tests knowing some basic components will help in understanding the code better. Writing tests with espresso is easy as its construction is similar to English language. The three major components are  ViewActions        : Allows you to interact with views ViewAssertions   : Allows you to assert the state of a view. ViewMatchers     : Allows you to locate a view in the current view hierarchy. Suppose we want to test if text is displayed in the view, we can do it by onView(withId(R.id.textView))                 //ViewMatcher .perform(click())                            //ViewAction .check(matches(isDisplayed()));              //ViewAssertion Example Consider an app which takes a name from the user and displays it on the next screen on clicking the button. To perform this kind of test we will write //Locate the view with id "name" and type the text "Natalie" onView(withId(R.id.name)).perform(typeText("Natalie")); //Locate the view with id "next" and click on it onView(withId(R.id.next)).perform(click()); //Locate the view with id "new_name" and check its text is equal with "Natalie" onView(withId(R.id.new_name)).check(matches(withText("Natalie"))); You can run tests by right clicking on the class and selecting the “run test” option. If the interaction is not as expected then the message will be displayed. Up until now unit test were in main focus but as we move towards the more complex apps where user interaction plays an essential role, UI testing becomes equally necessary. References: https://developer.android.com/topic/libraries/testing-support-library/index.html#ajur-junit https://developer.android.com/training/testing/ui-testing/espresso-testing.html#build

Continue ReadingTesting User Interactions with Espresso

Intro to concurrency and Refactoring Open Event Android using RxJava

Functional reactive programming seems to have taken the whole development world by storm. It’s one of the hottest thing even after 2 years of constant traction in the communities of several programming languages, where different implementations of the specifications defined by Rx or Reactive Extensions have changed the paradigm of programming for many professional and enthusiast developers. RxJava is no exception, not only has it been widely adopted by Android and Java developers unanimously, but also received attention of well known and top developers of both communities. The reason of its success is the fluent API with heavy toolset it provides from the Functional Programming paradigm and its ease and natural ability to handle concurrency on different levels based on the type of operation being performed, i.e., computations, I/O, etc. It basically takes away the several constraints and concurrency related checklists developers had to maintain while working with thread management. So, now, developers can’t make an excuse for using database operations on the Main Thread because offloading it on another thread is hard. So, in this blog post, I will be detailing the process of converting the existing synchronous code of your app into a performant reactive code without breaking the structure of your project, like we did in Open Event Android (Github Repo). Before starting, I have assumed that you know how to add RxJava dependency to your project as it is covered in many other blog posts and the documentation is also very clear. Secondly, you should also add RxAndroid dependency as it contains the Scheduler needed to work on Android’s Main Thread. So, Let’s start. Current State Currently, our code loads the queries from database synchronously on Main Thread using the SQLiteDatabase for an Android application. This is how it looks like - As we can see, we are directly returning the loaded results to the caller. This is called synchronous call, meaning the caller will block till the function is returned, and can’t move further to do anything else. It basically waits for the function to return, which may take hundreds of milliseconds to seconds based on the function it performs. New Android version crash the applications that perform Network interactions on the main thread but no such restriction for disk based operations is there, making it hard to enforce best performance practices. Before RxJava, there were interfaces made for different kinds of objects, passed in as parameters of the db request function, which created a new thread and performed operations and when completed, returned back the results to the main thread using the postOnUiThread method, so that the views could update themselves. The interface implementations passed are called callbacks because they call a particular function that you provide back when the asynchronous operation is completed. Even the calling of callback function is delegated on the implementor and may result in undesired effects. The query done in this fashion is called an asynchronous query because the execution of this takes place in parallel with main thread…

Continue ReadingIntro to concurrency and Refactoring Open Event Android using RxJava

Integrating an Image Editing Page in Phimpme Android

The main aim of the Phimpme is to develop image editing and sharing application as an alternative to proprietary solutions like Instagram. Any user can choose a photo from the gallery or click a picture from the camera and upload it on the various social media platform including Drupal and wordpress. As most of the image editor applications in the app store currently my team and I discussed and listed down the basic functionality of the Image editing activity. We have listed down the following features for image Editing activity: Filters. Stickers Image tuning Choosing the Image Editing Application There are number of existing Open Source projects that we went through to check how they could be integrated into Phimpme. We looked into those projects which are licensed under the  MIT Licence. As per the MIT Licence the user has the liberty to modify the use the code, modify it, merge, publish it without any restrictions. Image-Editor Android is one such application which has MIT Licence. The Image-Editor Android has extensive features for manipulating and enhancing the image. The features are as follows: Edit Image by drawing on it. Applying stickers on the image. Applying filters. Crop. Rotating the image. Text on the image. It is an ideal application to be implemented in our project. The basic flow of the application First, getting the image either by gallery or camera. The team has implemented leafPic and openCamera. Second, redirecting the image from the leafPic gallery to the Image editing activity by choosing edit option from the popup menu. Populating the Menu in the popup menu in XML: <menu> tag is the root node, which contains ites in the popup menu. The following code is used to populate the menu: <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android">    <item android:id="@+id/action_edit"          android:icon="@drawable/ic_edit"          android:title="@string/Edit"          android:showAsAction="ifRoom"/>    <item android:id="@+id/action_use_as"          android:icon="@drawable/ic_use_as"          android:title="@string/useAs" /> </menu> Setting up the Image Editing Activity Image-Editor Android application contains two main sections. MainActivity (To get the image). imageeditlibrary(To edit the image) We need to import imageeditlibrary module. Android studios gives easy method to import a module from any other project using GUI. This can be done as follows: File->new->import module then choosing the module from the desired application. Things to remember after importing any module from any other project: Making sure that the minSdkVersion and targetSdkVersion in the gradle of the imported module and the current working project is same. In Phimpme the minSdkVersion is 16 and tagetSdkVersion is 25, which is used as standard SDK version. Importing all the classes in the used in the imageeditlibrary module before using them in the leadPic gallery. Sending Image to Image Editing Activity This includes three tasks: Handling onclick listeners. Sending the image from the leafPic Activity Receiving the the image in EditImageActivity. Handling onClick Listener: public boolean onOptionsItemSelected(MenuItem item) {        switch (item.getItemId()) { case R.id.action_edit: // setOnclick listener here.  } } Sending Image to EditImageActivity: First we need to get the path of the image to be send. For this we need FileUtils class to…

Continue ReadingIntegrating an Image Editing Page in Phimpme Android

Use of ViewPager in Phimpme

Previously GalleryView was used in phimpme android app but as it is now deprecated, I decided to use ViewPager instead of GalleryView. ViewPager allows us to view data with a horizontal swipe with the help of layoutManager. Steps to implement the viewPager: First, add the ViewPager in Activity.xml file where you want to implement the ViewPager. This can be done using the line of code below: <android.support.v4.view.ViewPager            android:id="@+id/view_pager"               android:layout_width="match_parent"              android:layout_height="match_parent"> </android.support.v4.view.ViewPager>  To display the content of viewPager we use the viewPagerAdapter. Create new java file ViewPagerAdapter and extends it to PagerAdapter. ViewPagerAdapter.java public class ViewPagerAdapter extends PagerAdapter { } After extending to PagerAdaper we have to override the two basic methods of PagerAdapter. First, implement the constructor which helps us to provide the context of activity to ViewPagerAdapter. You can override by pressing Alt+enter combination, click on “implement methods” and then selects these two methods. It will implement two methods   getCount() isViewFromObject() getCount will return the number of items in view pager. Now we override the few methods which are required to inflate and destroy view in viewPager. First, Override the instantiateItem() method it creates the page for given position. @Override public Object instantiateItem(ViewGroup container, int position) { return super.instantiateItem(container, position); } Now we will modify this method to inflate the view for viewPager. As we want to display imageView in viewPager first we have to inflate the imageView and set Image according to the position of ViewPager. Next steps, Implement the customView for imageView. And provide the data for  ViewPager i.e Array of images. Create new custom_layout.xml and add ImageView in it. <ImageView   android:layout_width="match_parent"   android:id="@+id/image_view"   android:layout_height="match_parent" /> And create an array for images if you want to show images from the local memory so collect path of the images which you want to show with the array name Images. Now we will use custom_layout layout in our ViewPager instantiateItem() method. @Override public Object instantiateItem(ViewGroup container, int position) {   LayoutInflater layoutInflater = (LayoutInflater)  context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);   View view=  layoutInflater.inflate(R.layout.custom_view,null);   ImageView imageView = (ImageView)view.findViewById(R.id.image_view);   imageView.setBackgroundResource(images[position]);   container.addView(view,0);   return view; } The above code inflates the imageView in ViewPager. Now we have to override destroyItem() method.  This method will destroy the content of viewPager from given position. The below code will remove the view which we added in instantiateItem() method. @Override public void destroyItem(ViewGroup container, int position, Object object) {  container.removeView((View) object); } Now PagerAdapter is ready, we can use this in our Activity. Reference the viewPager and set the ViewPagerAdapter to ViewPager. Activity.java @Override protected void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentView(R.layout.activity_main);   ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);   viewPager.setAdapter(new ViewPagerAdapter(this)); } The above code will set the pagerAdapter to our viewPager and display the content which we defined in instantiateItem() method of pagerAdapter.   This is how viewPager will allow viewing images by swiping horizontally in Phimpme. Resources: https://developer.android.com/reference/android/support/v4/view/PagerAdapter.html https://github.com/fossasia/phimpme-android/pull/407/files

Continue ReadingUse of ViewPager in Phimpme

Debugging Using Stetho in Open Event Android

The Open Event Android project helps event organizers to generator Apps (apk format) for their events/conferences by providing api end point or zip generated using Open Event server. In this android app data is fetched from the internet using network calls to the Open Event server and the data of the event is stored in a database. It is difficult to debug an app with so many network calls and database connectivity. A way to approach this is using  Stetho which is very helpful tool for debugging an app which deals with network calls and database.   Stetho is Facebook’s open source project works as debug bridge for android applications which gives powerful Chrome Developers Tools for debugging android applications using Chrome desktop browser. What can you do using stetho ? Analyze network traffic Inspect elements(layouts/views)   View SQLite database in table format Run queries on SQLite database View shared preference and edit it Manipulate android app from command line Setup 1. Add Gradle dependency To add stetho in your app add ‘com.facebook.stetho:stetho:1.5.0’ dependency in your app  module’s build.gradle file. This dependency is strictly required. dependencies{ compile 'com.facebook.stetho:stetho:1.5.0' } For network inspection add one of the following dependency according to which you will be using 'com.facebook.stetho:stetho-okhttp:1.5.0' 'com.facebook.stetho:stetho-okhttp3:1.5.0' 'com.facebook.stetho:stetho-urlconnection:1.5.0' 2. Initialize stetho Initialize stetho in class MyApplication which extends Application class by overriding  onCreate() method. Make sure you have added MyAppication in manifest. public class MyApplication extends Application { public void onCreate() { super.onCreate() Stetho.initializeWithDefaults(this); } } Stetho.initializeWithDefaults(this) initializes stetho with defaults configuration(without network inspection and more). It will be able to debug database. Manifest file <Application   android:name=”.MyApplication”    …   /> For enabling network inspection add StethoInterceptor  in OkHttpClient new OkHttpClient.Builder()    .addNetworkInterceptor(new StethoInterceptor())    .build(); Using Chrome Developer Tools 1. Open Inspect window Run stetho initialized app on device or emulator then start Google chrome and type chrome://inspect. You will see you device with your app’s package name. Click on “inspect”2. Network Inspection Go to Network tab. It will show all network calls. With almost all info like url(path), method, returned status code, returned data type, size, time taken etc. You can also see preview of image and preview, response of returned json data by clicking on Name. 3. SQLite Database Go to “Resources”  tab and select “Web SQL”. You will see database file(.db). By clicking on database file you will see all tables in that database file. And by clicking on table name you will see data in row-column format for that table. 4. Run queries on SQLite database Same as above go to “Resources”  tab and select “Web SQL”. You will see database file(.db). By clicking on database file you will see console on right side, where you can run queries on SQLite database. Example, SELECT * FROM tracks ; 5. Shared Preferences Inspection Go to “Resources”  tab and select “Local Storage”. You will show all files that your app used to save key-value pairs in shared preference and by clicking on file you will see all key-value pairs. 6. Element(View/Layout) Inspection…

Continue ReadingDebugging Using Stetho in Open Event Android
Read more about the article Set spacing in RecyclerView items by custom Item Decorator in Phimpme Android App
Spacing in RecyclerView GridLayoutManager

Set spacing in RecyclerView items by custom Item Decorator in Phimpme Android App

We have decided to shift our images Gallery code from GridView to using Grid Layout manager in RecyclerView in Phimpme Android application. RecyclerView has many advantages as compare to Grid/ List view. Advantages of using layout manager either List, Grid or Staggered. We can use many built in animations. Item decorator for customizing the item. Recycle items using the View Holder pattern Recycler View documentation Adding recyclerview in xml <android.support.v7.widget.RecyclerView    android:layout_width="match_parent"    android:layout_height="match_parent"    android:id="@+id/rv"    /> Setting layout manager mLayoutManager = new GridLayoutManager(this, 3); recyclerView.setLayoutManager(mLayoutManager); In phimpme we have an item as an ImageView, to show into the grid. Setup the Grid using layout manager as above. Gallery of images is set but there is no spacing in between grid items. Padding will not help in this case. Found a way to set offset by creating a Custom item decoration class. Add a constructor with parameter as a dimension resource.   public class ItemOffsetDecoration extends RecyclerView.ItemDecoration {   private int mItemOffset;   public ItemOffsetDecoration(int itemOffset) {       mItemOffset = itemOffset;   }   public ItemOffsetDecoration(@NonNull Context context, @DimenRes int itemOffsetId) {       this(context.getResources().getDimensionPixelSize(itemOffsetId));   }   @Override   public void getItemOffsets(Rect outRect, View view, RecyclerView parent,           RecyclerView.State state) {       super.getItemOffsets(outRect, view, parent, state);       outRect.set(mItemOffset, mItemOffset, mItemOffset, mItemOffset);   } } Author: gist.github.com/yqritc/ccca77dc42f2364777e1 Usage: ItemOffsetDecoration itemDecoration = new ItemOffsetDecoration(context, R.dimen.item_offset); mRecyclerView.addItemDecoration(itemDecoration) Pass the item_offset value in the function. Go through the material design guidelines for a clear understanding of dimensions in item offset.

Continue ReadingSet spacing in RecyclerView items by custom Item Decorator in Phimpme Android App

Control flow of SUSI AI on Android and database management using Realm

While developing a chat based android application, one of the most important things is keeping track of user’s messages. Since the user might want to access them in the absence of Internet connectivity (i.e remotely) as well, storing them locally is also important. In SUSI we are using Realm to keep things organized in a systematic manner and constructing model (or adding appropriate attributes) for every new data type which the application needs. Right now we have three main models namely ChatMessage, WebLink and WebSearchModel. These three java classes define the structure of each possible message.  ChatMessage evaluates and classifies incoming response from server either to be an image or map or pie chart or web search url or other valid types of response. WebSearchModel and WebLink models are there to manage those results which contains link to various web searches. Various result based lists are maintained for smooth flow of application. Messages sent in absence of Internet are stored in a list - nonDelivered. All the messages have an attribute isDelivered which is set to true if and only if they have been queried, otherwise the attribute is set to false which puts it in the nonDelivered list. Once the phone is connected back to the internet and the app is active in foreground, the messages are sent to server, queried and we get the response back in the app’s database where the attributes are assigned accordingly.   I will explain a functionality below that will give a more clear view about our coding practices and work flow. When a user long taps a message, few options are listed(these actions are defined in recycleradapters->ChatFeedRecyclerAdapter.java) from which you may select one. In the code, this triggers the method onActionsItemClicked(). In this Overridden method, we handle what happens when a user clicks on one of the following options from item menu. In this post I’ll be covering only about the star/important message option. case R.id.menu_item_important: nSelected = getSelectedItems().size(); if (nSelected >0) { for (int i = nSelected - 1; i >= 0; i--) { markImportant(getSelectedItems().get(i)); } if(nSelected == 1) { Toast.makeText(context,nSelected+" message marked important",Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, nSelected + " messages marked important", Toast.LENGTH_SHORT).show(); } Important = realm.where(ChatMessage.class). equalTo("isImportant",true) .findAll().sort("id"); for(int i=0;i<important.size();++i) Log.i("message ","" + important.get(i).getContent()); Log.i("total ",""+important.size()); actionMode.finish(); } return true; We have the count of messages which were selected. Each message having a unique id is looped through and the attribute “isImportant” of each message object is modified accordingly. To modify this field, We call the method markImportant() and pass the id of message which has to be updated. public void markImportant(final int position) { realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { ChatMessage chatMessage = getItem(position); chatMessage.setIsImportant(true); realm.copyToRealmOrUpdate(chatMessage); } }); } This method copies the instance of the message whose id it has received and updates the attribute “isImportant” and finally updates the message instance in the database. Below given is the code for ImportantMessage activity which will help you understand properly how lists are used…

Continue ReadingControl flow of SUSI AI on Android and database management using Realm

UI Testing in Phimpme Android

Espresso is an Android Testing tool which helps developers to write UI based tests. After writing tests, developers can make use of Android studio to run the tests or can implement a method in various Continuous integration sites like Travis CI to run the tests on a new push or a pull request. I implemented Espresso tests in the Phimpme Android project of FOSSASIA to test the basic UI elements of the home screen, camera view and the settings activity. Steps to Add the UI tests : The first step is to import the packages related to the instrumentation tests and configure the build.gradle file of the application to add certain dependencies. This can be done using the line of code below: dependencies { androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' } To ensure best test results make sure that you turn off the device animations. For this go to developer options and disable the: Window animation scale Transition animation scale Animator duration scale After doing the above, your developer options screen should look like the screenshot below with all the animation scale disabled. Create the java class for the android test with the name of the activity you want to test followed by the word Test. Suppose you want to create a test for your MainActivity. Make a test class with the name MainActivityTest. Define your tests with annotations @LargeTest @RunWith(AndroidJUnit4.class) and define the MainActivity Test. Define the Test activity rule with the annotation @Rule and mention the java class which you want to test. I’ll be explaining the codes exactly as I used to add espresso test in Phimpme Android application below. In this for testing the PhimpMe.class, I used the following codes @Rule public ActivityTestRule<PhimpMe> mActivityTestRule = new ActivityTestRule<>(PhimpMe.class); The codes from defining the tests to defining the rules are given below: @LargeTest @RunWith(AndroidJUnit4.class) public class MainActivityTest { @Rule public ActivityTestRule<PhimpMe> mActivityTestRule = new ActivityTestRule<>(PhimpMe.class); After this, start writing the tests with the @Test annotations, the code as I used to test the Load more photos button in the MainActivity of the Phimpme Application is shown below: @Test ViewInteraction imageView = onView( allOf(withId(R.id.btnLoadMoreLocalPhotos), childAtPosition( allOf(withId(R.id.titlebarLocalPhotos), childAtPosition( IsInstanceOf.instanceOf(android.widget.LinearLayout.class), 0)), 1), isDisplayed())); imageView.check(matches(isDisplayed()));   The above code checks whether the plus button in the top right corner is visible in the UI. For the complete code, please refer to the Phimpme Android Repository of FOSSASIA or refer to this pull request in which I added tests for all the Activities and Fragments of the Phimpme Android Application. Since we are rebuilding the application by modifying the whole view of the application, the tests are currently removed. As soon as the application becomes fairly stable, I will be adding the Tests in this in the same way. For complete tutorial on setting up the test using the Android Studio Inbuilt functionality. Refer to : https://developer.android.com/studio/test/espresso-test-recorder.html#run-an-espresso-test-with-firebase-test-lab That’s it for now. Thanks! Resources : https://developer.android.com/training/testing/ui-testing/espresso-testing.html https://github.com/fossasia/phimpme-android/pull/85/files https://developer.android.com/studio/test/espresso-test-recorder.html#run-an-espresso-test-with-firebase-test-lab

Continue ReadingUI Testing in Phimpme Android

Porting PSLab Libraries – Python to Java

PSLab has existing communication libraries and sensor files in Python which were created during the development of Python Desktop Application. The initial task and challenge was porting this existing code to Java to be used by the Android App. Since, the python libraries also utilized the object oriented model of programming, porting from Python to Java had the similar code structure and organization. Common problems faced while porting from Python to Java The most common problem is explicitly assigning data types to variables in Java since Python manages data types on its own. However, most of the time the data types are quite evident from the context of their use and understanding the purpose of the code can make the task much simpler. Another task was migrating the Python data structures to their corresponding Java counterparts like a List in Python represents an ArrayList in Java, similarly a Dictionary corresponds to a HashMap and so on. Some of the sections of the code uses highly efficient libraries like Numpy and Scipy for some mathematical functions. Finding their corresponding Java counterparts in libraries was a challenge. This was partly solved by using Apache Common Math which is a library dedicated for mathematical functions. Some of the functions were directly implemented using this library and for rest of the portions, the code was written after understanding the structure and function of Numpy methods. While porting the code from Python to Java, some of the steps which we followed: Matching corresponding data-structures The Dictionary in python... Gain_scaling = OrderedDict ([('GAIN_TWOTHIRDS', 0.1875), ('GAIN_ONE', 0.125), ('GAIN_TWO', 0.0625), ('GAIN_FOUR', 0.03125), ('GAIN_EIGHT', 0.015625), ('GAIN_SIXTEEN', 0.0078125)]) ...was mapped to corresponding Java HashMap in the manner given below. A point to be noted here is for adding elements to a HashMap can be done only from a method and not at the time of declaration of HashMap. private HashMap <String,Double> gainScaling = new HashMap <String,Double>(); gainScaling.put("GAIN_TWOTHIRDS",0.1875); gainScaling.put("GAIN_ONE",0.125); gainScaling.put("GAIN_TWO",0.0625); gainScaling.put("GAIN_FOUR",0.03125); gainScaling.put("GAIN_EIGHT",0.015625); gainScaling.put("GAIN_SIXTEEN",0.0078125); Similarly, the List in Python can be  be converted to the corresponding ArrayList in Java. Assigning data types and access modifiers to corresponding variables in Java POWER_ON = 0x01 gain_choices = [RES_500mLx, RES_1000mLx, RES_4000mLx] ain_literal_choices = ['500mLx', '1000mLx', '4000mLx'] scaling = [2, 1, .25] private int POWER_ON = 0x01; public int[] gainChoices = {RES_500mLx,RES_1000mLx,RES_4000mLx}; public String[] gainLiteralChoices = {"500mLx", "1000mLx", "4000mLx"}; public double[] scaling = {2,1,0.25}; Assigning data types and the corresponding access modifiers can get tricky sometimes. So, understanding the code is essential to know whether a variable in limited to the class or needs to be accessed outside the class, whether a variable is int, short, float or double etc. Porting Numpy & Scipy functions to Java using Apache Common Math For example, this piece of code gives the pitch of acceleration. It uses mathematical functions like arc-tan. pitchAcc = np.arctan2(accData[1], accData[2]) * 180 / np.pi The corresponding version of arc-tan in Apache Common Math is used in Java. double pitchAcc = Math.atan2(accelerometerData[1], accelerometerData[2]) * 180 / pi; Porting by writing the code for Numpy and…

Continue ReadingPorting PSLab Libraries – Python to Java

Adding swap space to your DigitalOcean droplet, if you run out of RAM

The Open Event Android App generator runs on a DigitalOcean. The deployment runs on a USD 10 box, that has 1 GB of RAM, but for testing I often use a USD 5 box, that has only 512mb of RAM. When trying to build an android app using gradle and Java 8, there could be an issue where you run out of RAM (especially if it's 512 only). What we can do to remedy this problem is creating a swapfile. On an SSD based system, Swap spaces work almost as fast as RAM, because SSDs have very high R/W speeds. Check hard disk space availability using df -h There should be an output like this Filesystem Size Used Avail Use% Mounted on udev 238M 0 238M 0% /dev tmpfs 49M 624K 49M 2% /run /dev/vda1 20G 1.1G 18G 6% / tmpfs 245M 0 245M 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 245M 0 245M 0% /sys/fs/cgroup tmpfs 49M 0 49M 0% /run/user/1001 The steps to create a swap file and allocating it as swap are sudo fallocate -l 1G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile We can verify using sudo swapon --show NAME TYPE SIZE USED PRIO /swapfile file 1024M 0B -1 And now if we see RAM usage using free -h , we'll see total used free shared buff/cache available Mem: 488M 37M 96M 652K 354M 425M Swap: 1.0G 0B 1.0G Do not use this as a permanent measure for any SSD based filesystem. It can corrupt your SSD if used as swap for long. We use this only for short periods of time to help us build android apks on low ram systems.

Continue ReadingAdding swap space to your DigitalOcean droplet, if you run out of RAM