Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Android Networking Bare Skin – Understanding JPost

  • Last Updated : 17 Aug, 2021

If you want to create bottom-to-top networking on Android, it is usually quite complicated. As a result, we rely on third-party libraries. But you’ll never know what’s beneath it. In this example, I’ve used the networking java.net package to create a networking framework driven by JPost, a class communication framework.

JPost

This is a Java / Android library that allows classes to communicate in a modular, asynchronous, and regulated manner. The following are the major characteristics of this library:

  • In contrast to previous pub-sub libraries, it has a weak reference to the subscribers. As a result, it does not cause memory leaks.
  • A single message can be sent to a subset of subscribers. This prevents the issue of an event from being received in an unfavorable location. As a result, the likelihood of aberrant application behavior is reduced.
  • Private channels can be used to manage subscriber addition. It reduces the possibility of inadvertently subscribing to subscribers and receiving unwanted communications.
  • It is a little library (55kb). As a result, the total size of the application is unaffected.
  • It enables both synchronous and asynchronous message transmission and processing.
  • It offers a technique for asynchronously running programs.

What exactly are we going to construct?

We will create an Android application that will perform network calls to retrieve a user’s repositories and display them in a ListView. The outcome is seen in the screenshot below.

Step #1: 

Begin by creating an Android Studio project and selecting the “Empty Activity” template. After choosing the empty activity we are now ready to get things done and make the project happen. Import the following libraries into the app’s module’s build.gradle:

dependencies {
    implementation 'com.geeks-for-geeks-jpost:0.0.4'
    implementation 'com.google.code.gson:gson:2.7'
}

GeekTip: Json is a well-known JSON parsing library. It aids in the conversion of an object to a json object and vice versa. As previously stated, JPost is a class communication library.

Step #2: Design the MainActivity layout

We will now be doing the hefty task of designing the UI, which will be usually basic, as this is only a tutorial.

XML




<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/gfg_main_activity"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="gfg.MainActivity">
    <ListView
        android:id="@+id/gfgListView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </ListView>
</LinearLayout>

GeekTip: It features a ListView to display the elements in a vertical list.

Step #3: Create the list item view layout

Just like the previous step you now need to create a list item view as done in Step #2, simply do the following to create it:

XML




<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp"
        android:gravity="center|left">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/grey"
            android:textSize="16sp"
            android:minWidth="65dp"
            android:text="@string/gfg_repo_sample"
            />
        <TextView
            android:id="@+id/repoIdTxt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/grey"
            android:textSize="16sp"
            android:layout_marginLeft="10dp"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp"
        android:gravity="center|left">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/grey"
            android:textSize="16sp"
            android:minWidth="65dp"
            android:text="@string/repo_name"
            />
        <TextView
            android:id="@+id/repoNameTxt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/grey"
            android:textSize="16sp"
            android:layout_marginLeft="10dp"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp"
        android:minWidth="65dp"
        android:gravity="center|left">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/grey"
            android:textSize="16sp"
            android:minWidth="65dp"
            android:text="@string/repo_url"
            />
        <TextView
            android:id="@+id/repoUrlTxt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/grey"
            android:textSize="16sp"
            android:layout_marginLeft="10dp"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp"
        android:gravity="center|left">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/grey"
            android:textSize="16sp"
            android:minWidth="65dp"
            android:text="@string/repo_size"
            />
        <TextView
            android:id="@+id/gfgRepoSize"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/grey"
            android:textSize="16sp"
            android:layout_marginLeft="10dp"/>
    </LinearLayout>
</LinearLayout>

GeekTip: It has four-row views that display four properties from the API response.

Step #4: Create a class that extends android.app called GeeksforGeeks

Utilization: We wish to initialize the networking framework that we are developing. As a result, we must specify when the program starts.

Java




public class GeeksforGeeks extends android.app.Application {
    @Override
    public void onCreate() {
        // Simply call the super method
        super.onCreate();
          // Add the API handler here
        sampleAPIHandler.init();
    }
}

Step #5: Create a data model class that will be built from the JSON response

Towards the end, the last thing which we need to do is simply create a data model class that will enable us to fetch and set the data which we got calling the API. 

Java




public class GfgRepoGit {
    @SerializedName("sno")
    private Integer sno;
    @SerializedName("specimen_name")
    private String specimen_name;
    @SerializedName("url ")
    private String url;
    @SerializedName("weight")
    private Integer weight;
    public Integer fetchID() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String fetchname() {
        return theName;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public Integer getWeight() {
        return weight;
    }
    public void setWeight(Integer size) {
        this.size = weight;
    }
}

GeekTip:“@SerializedName” is a JSON library annotation that maps the variable to the JSON key.

Step #6: Create the GitRepoMsg class

Now we will be creating a GfGRepoMsg class which will be used as a message to transmit the parsed JSON response on the channel that we will construct later.

Java




public class GfGRepoMsg{
    private static List< GfGRepoMsg> gfgRepoList;
    public GfGRepoMsg (List<GitRepo> gitRepoList) {
        this.gitRepoList = gitRepoList;
    }
    public List<GitRepo> getGfgRepo() {
        return gfgRepo;
    }
    public void setGitRepoList(List<gfgRepo> gitRepoList) {
        this.gitRepoList = gitRepoList;
    }
}

Step #7: Make a listview adapter called gfgRepoList to populate the ListView

The next step is obviously to create a gfgRepoList adapter and then populate the list view which will set the data; 

Java




public class gfgRepoList extends BaseAdapter {
    private List<gfgRepoList> gfgRepoList;
    private Context gfgcontext;
  
    public RepoListAdapter(Context gfgcontext, List<gfgRepoList> gfgRepoSize) {
        this.gfgcontext  = gfgcontext;
        this.gfgRepoSize = gfgRepoSize;
    }
  
    @Override
    public int getCount() {
        return gfgRepoSize.size();
    }
  
    @Override
    public Object getItem(int someGfgPosition) {
        return gfgRepoSize.get(someGfgPosition);
    }
  
    @Override
    public long getItemId(int someGfgPosition) {
        return someGfgPosition;
    }
  
    @Override
    public View getView(int someGfgPosition, View gfgView, ViewGroup parent) {
  
        final ViewHolder holder;
        if(gfgView == null){
            gfgView = LayoutInflater.from(gfgcontext).inflate(R.layout.gfg_list_item,parent,false);
            holder = new ViewHolder();
            gfgView.setTag(holder);
        }else{
            holder=(ViewHolder)gfgView.getTag();
        }
  
        holder.geeksRepoIdTxt = (TextView)gfgView.findViewById(R.id.sampleRepo);
        holder.geeksRepoNameTxt = (TextView)gfgView.findViewById(R.id.sampleName);
        holder.geeksRepoUrlTxt = (TextView)gfgView.findViewById(R.id.sampleUrl);
        holder.geeksRepoSizeTxt = (TextView)gfgView.findViewById(R.id.sampleRepo);
  
        gfgRepoList geeksRepo = gfgRepoSize.get(someGfgPosition);
        holder.geeksRepoIdTxt.setText(String.valueOf(geeksRepo.getId()));
        holder.geeksRepoNameTxt.setText(geeksRepo.getName());
        holder.geeksRepoUrlTxt.setText(geeksRepo.getUrl());
        holder.geeksRepoSizeTxt.setText(String.valueOf(geeksRepo.getSize()));
  
        return gfgView;
    }
  
    private class ViewHolder{
        TextView geeksRepoIdTxt;
        TextView geeksRepoNameTxt;
        TextView geeksRepoUrlTxt;
        TextView geeksRepoSizeTxt;
    }
  
    public void setgfgRepoListList(List<gfgRepoList> gfgRepoSize) {
        this.gfgRepoSize = gfgRepoSize;
        notifyDataSetChanged();
    }
}

GeekTip: The adapter is given a list of GitRepo objects to populate the list item views with. The setGitRepoList function re-initializes the list and calls the repopulateListItemViews method to populate the list item views with fresh data.

Step #8: To manage the API calls, create the sampleAPIHandler class

Let’s take a look at this class first, and then we’ll try to comprehend it:

Java




public class sampleAPIHandler{
  
    public static String GIT_REPO_URL = "https://api.github.com/users/the-rebooted-coder/repos";
  
    private static final int RANDOM_CHANNEL_ID  = 1000;
    private static sampleAPIHandler sampleapihandler;
  
    public static void init(){
        sampleapihandler = new sampleAPIHandler();
    }
  
    public sampleAPIHandler() {
        try {
            JPost.getBroadcastCenter().createPrivateChannel(this, RANDOM_CHANNEL_ID );
        }catch (Exception e){
            e.printStackTrace();
        }
    }
  
    public static void DOASERVICECALL(String url){
        try {
            JPost.getBroadcastCenter().broadcastAsync(sampleapihandler, RANDOM_CHANNEL_ID , url);
        }catch (JPostNotRunningException e){
            e.printStackTrace();
        }
    }
  
    @OnMessage(channelId = RANDOM_CHANNEL_ID )
    public void processGitRepoGet(String url) {
        try {
            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();
            con.setRequestMethod("GET");
  
            int responseCode = con.getResponseCode();
            Log.d("Debug", "GEEKS FOR GEEKS : " + responseCode);
  
            if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader in = new BufferedReader(
                        new InputStreamReader(con.getInputStream()));
                String inputLine;
                StringBuffer response = new StringBuffer();
  
                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();
  
                Log.d("Debug", "Response : " + response);
                GEEKSSONBuilder builder = new GEEKSSONBuilder();
                GEEKSSON GEEKSSON = builder.create();
  
                GitRepo[] gitRepoArray = GEEKSSON.fromJson(response.toString(), GitRepo[].class);
                JPost.getBroadcastCenter().broadcastAsync(new GitRepoMsg(Arrays.asList(gitRepoArray)));
            }
        }catch (MalformedURLException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }catch (JPostNotRunningException e){
            e.printStackTrace();
        }
    }
}

GeeksTip: GIT GFG is defined to make referencing the API endpoint from any class easier. SAMPLE_CHANNEL_ID is the int id that we wish to associate with a private channel that we’ve created using JPost. JPost offers three types of channels. The default, public, and private channels are used to connect with users in a regulated manner. Only the Creator may add subscribers to this channel, and only subscribers can publish messages on it. For additional information, please visit JPost.

The ApiHandler class is instantiated using the init function.

Step #9: Creating the MainActivity

The last step which we need to perform is to create the main activity which we will use for the data fetch:

Java




public class MainActivity extends AppCompatActivity {
  
    private ListView GFGREPOLIST;
    private RepoListAdapter GFGLIST;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        GFGREPOLIST = (ListView) findViewById(R.id.GFGREPOLIST);
        GFGLIST = new RepoListAdapter(getApplicationContext(), new ArrayList<GitRepo>());
        GFGREPOLIST.setAdapter(GFGLIST);
        try {
            JPost.getBroadcastCenter().addSubscriber(this);
        }catch (Exception e){
            e.printStackTrace();
        }
        SAMPLEAPIHANDLER.DOSERVICECALL(SAMPLEAPIHANDLER.GIT_REPO_URL);
    }
  
    @OnUiThread
    @OnMessage
    private void onGitRepoList(GitRepoMsg msg){
        if(msg.getGitRepoList() != null) {
            GFGLIST.setGitRepoList(msg.getGitRepoList());
        }
    }
}

GeekTip: 

  • Using the addSubscriber(object) function, MainActivity subscribes to JPost’s Default Channel.
  • “@OnUiThread” : It’s an annotation provided to Android. To know more about annotation in android, click here
  • It receives the response message over the global default channel and refreshes the listview.

Conclusion

That’s it! You may thank JPost for creating such a simple and strong networking infrastructure. This was an example of a guideline. The road to a fully developed system is left as an exercise.


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!