Today is going to be a quick and short post. We are going to learn how to send an HTTP Post request using an Asynctask.

Recently, all we’ve been doing with AsyncTask is sending an HTTP Get request, we were getting result from the server. However, there are times where you want to send data to the server, and to do that, you send an HTTP Post request.

We will maintain loose coupling that we have learned earlier, orientation handling, and network handling. We build on top of what we’ve previously learned.

You can download the latest code in Java or Kotlin from github.

Now, let’s start coding.

Create a new class and name it AsyncTaskPost, below is the implementation of doInBackground method:

  1. @Override
  2. protected String doInBackground(String...params){
  3. try{
  4. URL url = new URL(params[0]);
  5. HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
  6. httpURLConnection.setRequestMethod("POST");//important
  7. httpURLConnection.connect();
  8. //write data to the server using BufferedWriter
  9. BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(httpURLConnection
  10. .getOutputStream()));
  11. writer.write(postData);
  12. writer.flush();
  13. //get response code and check if valid (HTTP OK)
  14. int responseCode = httpURLConnection.getResponseCode();
  15. if(responseCode == 200){//if valid, read result from server
  16. BufferedReader reader = new BufferedReader(new InputStreamReader
  17. (httpURLConnection.getInputStream()));
  18. String line;
  19. StringBuilder stringBuilder = new StringBuilder();
  20. while((line = reader.readLine()) != null){
  21. stringBuilder.append(line);
  22. }
  23. return stringBuilder.toString();
  24. }
  25. } catch (MalformedURLException e) {
  26. e.printStackTrace();
  27. } catch (IOException e) {
  28. e.printStackTrace();
  29. }
  30. return null;
  31. }

There are two things that are new in the above code:

  • Usage of BufferedWriter: When we POST to a server, we are writing data. To do that, we need to get an OutputStream, a stream that is responsible to send data, and wrap it with our BufferedWriter and write the data.
  • Checking response code: This is optional, but it’s good practice to do. When we connect and write our data, we need to check that everything was ok. So we check if response code from HTTP is equivalent to 200 (this is a constant value for OK and will never change). If everything went well, we read our data from the server as usual.

Now we need to implement onPostExecute method:

  1. @Override
  2. protected void onPostExecute(String result){
  3. Intent intent = new Intent("result");
  4. intent.putExtra("json", result);
  5. LocalBroadcastManager.getInstance(context.get().getApplicationContext()).sendBroadcast
  6. (intent);
  7. }

Nothing new, same as before. Broadcast the result where the Activity that is registered will receive the message.

In our MainActivity, create a BroacastReceiver:

  1. private BroadcastReceiver broadcastReceiverPost = new BroadcastReceiver() {
  2. @Override
  3. public void onReceive(Context context, Intent intent) {
  4. Bundle bundle = intent.getExtras();
  5. if(bundle != null){
  6. String result = bundle.getString("json");
  7. textView.setText(result);
  8. isJSONPosting = false;
  9. }
  10. }
  11. };

Register and unregister:

  1. @Override
  2. protected void onResume(){
  3. super.onResume();
  4. ...
  5. LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiverPost, new
  6. IntentFilter(BroadcastConstants.JSON_POST));
  7. }
  8. @Override
  9. protected void onPause(){
  10. super.onPause();
  11. ...
  12. LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiverPost);
  13. }

Finally, setup button:

  1. findViewById(R.id.buttonPost).setOnClickListener(e -> {
  2. executePostJSON();
  3. });
  4. private void executePostJSON(){
  5. isJSONPosting = true;
  6. if(hasInternetConnection()){
  7. try{
  8. JSONObject jsonObject = new JSONObject();
  9. jsonObject.put("comments", "just deliver")
  10. .put("custemail", "myemail")
  11. .put("size", "medium");
  12. JSONObject jsonObjectForm = new JSONObject().put("form", jsonObject);
  13. new AsyncTaskPost(new WeakReference<Context>(this), jsonObjectForm.toString(),
  14. BroadcastConstants.JSON_POST).execute("https://httpbin.org/post");
  15. }catch (JSONException jsonException){
  16. jsonException.printStackTrace();
  17. }
  18. }else{
  19. displayNoInternetDialog();
  20. }
  21. }

In executePostJSON() method, we are creating our JSONObject that we want to post, and then create an instance of AsyncTaskPost, passing our JSONObject. (for now, our JSONObject is static, later, we’ll see how to populate it from the user).

Run and test the application. Notice how everything we’ve done before still works smoothly with what we’ve added. This is the most important thing that any developer can learn, how to add code without breaking existing one.

However, there are still some things that need to be fixed. You might have noticed that some of the code is becoming redundant, we can identify three redundancies:

  • Registering and unregistering broadcast receivers: Notice how in onResume and onPause methods, how we are writing the same lengthy line of code to register/unregister a broadcast.
  • GetJSON and AsyncTaskPost: more than half of the code in doInBackground is identical. To make things worse, both have the EXACT same implementation in onPostExecute
  • implementation of onReceive method in broadcast receivers: They almost have an identical implementation, getting a bundle, check if not null, get a String, and do something with the String.
  • Boolean variables: We now have three boolean variables, one for each AsyncTask, and the same handling is done in each method that executes a task. In addition to same handling done when network is restored.

For now, keep the code as is. You have to implement something at first to recognize that it’s bad code, and then figure a way to fix the bad code. This is what we’ve been doing in the AsyncTask series all along. Solving the base problem, finding a problem, fixing it, finding a new problem, and so on.

All of the mentioned issues will be resolved in the next post.

That’s it for today’s post, short and simple.

As usual, the source code is available in Java and Kotlin on github.