1
\$\begingroup\$

I have a PHP API which echoes some data depending on the parameters in the URL:

URL = "MyWebsite.com/MyAPI.php/username/password"

When I try to access this API with Postman, I get the result within 5 seconds, however, using any Android device, I get the result at least 15 seconds later, under same network.

Now I suspect there might be a delay in the way I'm processing the data, but I'm also doubting that it's taking +10 seconds.

Here's the result from the API call:

{'Data1': Value1, 'Data2': 'Value2', 'Data3': 'Value3', 'Data4': 'Value4', 'Data5': 'Value5', 'Data6': 'Value6', 'Data7': 'Value7'}

Only the first value is integer, the rest are all string.

API Call code:

    apiTEST = view.findViewById(R.id.apiTEST);//Text View
    Button getUserData = view.findViewById(R.id.getUserData);
    String apiURL = "https://MyWebsite.com/MyAPI.php/username/password";
    new Handler().postDelayed(() -> {
        getUserData.performClick();
        apiTEST.setText(getResources().getString(R.string.please_wait));//Show please wait line
    }, 1000);//Automatically press the invisible button a second after loading the activity
    getUserData.setOnClickListener(v -> {
        StringRequest stringRequest = new StringRequest(apiURL,
                response -> showJSONS(view, response),
                error -> {
                    apiTEST.setText(error.getMessage());
                    getUserData.performClick(); //Sometimes an error occurs (null), so this line will just click the button automatically to make the request again
                });
        RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
        requestQueue.add(stringRequest);
    });

Data processing/showing:

   private void showJSONS(View view, String response) {
    response = response.replace("'", "").replace("\"", "").replace("{", "").replace("}","");
    String[] theValues = response.split(",");
    apiTEST = view.findViewById(R.id.apiTEST);
    for (String theValue : theValues) {
        if (theValue.contains("Data1")){
            String[] data1Line = theValue.split(":");
            String Data1 = data1Line[1];
            Data1 = Data1.replace("'", "");
            data1_field.setText(Data1);
        }
        else if (theValue.contains("Data2")){
            String[] data2Line = theValue.split(":");
            String data2 = data2Line[1];
            data2 = data2.replace("'", "");
            data2_field.setText(data2);
            data2ProgressBar[0] = data2;
        }
        else if (theValue.contains("Data3")){
            String[] data3Line = theValue.split(":");
            String data3 = data3Line[1];
            data3 = data3.replace("\"", "");
            data3_field.setText(data3);
            data3ProgressBar[0] = data3;
        }
        else if (theValue.contains("Data4")){
            String[] data4Line = theValue.split(":");
            String data4Value = data4Line[1];
            data4Value = data4Value.replace("\"", "");
            data4Value = data4Value.replace("}]}", "");
            data4_field.setText(data4Value);
            data4ProgressBar[0] = data4Value;
        }
        ... same for data5, data6 & data7
    }
    setButtonsVisibility(view, true);//Show buttons to interact with the values
    apiTest.setText("");//Remove the "Please Wait" line
  }

Although I have set the buttons visibility before removing the "Please wait" line, what actually happens in the app is that the "Please wait" line gets removed, then about 7 seconds later the buttons appear!

Is there a better approach to retrieving the data from the API? Or to process the data more effectively?

About the auto clicking the button automatically when an error occurs: If I try to use Postman, I get the result 10/10, never failed or showed any error, but through the app, sometimes I just get "null" so I can only get the result after retrying few times. Thanks.

\$\endgroup\$
4
  • \$\begingroup\$ Welcome to Stack Review, from your code you know you are receiving a json object , there is a specific reason why you chose to see it as a string and not a json object ? \$\endgroup\$ Nov 8 '21 at 9:30
  • \$\begingroup\$ Thank you, the only reason is that this will be the first version for the app, and I found it a little bit difficult for me to deal with JSON in Java, so I decided to deal with it as String, then on the next version I'll have more time to learn how to use it as JSON. \$\endgroup\$
    – KiDo
    Nov 8 '21 at 9:45
  • 1
    \$\begingroup\$ You are welcome, but with string you are inspecting the message several times while with json the inspection process (deserialization) is done just one time , so it is more convenient and almost surely explains the slowness. Not related to the question,if you want to be sure users receive your reply you have to write @ before the username, there is also the username autocomplete option. \$\endgroup\$ Nov 8 '21 at 11:04
  • \$\begingroup\$ Also retreiving 6 values of data should never take more then 5 seconds... I would expect something like maximum of 100ms \$\endgroup\$
    – Thallius
    Nov 8 '21 at 16:22
5
\$\begingroup\$

When approaching optimization problems (and it kinda is one as you want to make a call faster) its generally best to first make sure that you understand exactly what is happening so when in doubt - measure and debug.

Before doing any changes in the code I'd first set up debugger and probably some logs with timestamps (assuming you are testing on separate physical device - maybe emulator would be more useful?).

After you have tools that allow you to measure the code runtime - don't guess, locate the hotspot. When hotspot is known usually the solution becomes obvious (if its not then its a good moment to ask further questions).

Sorry if this is not the answer you were counting for but I believe that giving advice on code performance without specific measurement is exactly wrong - and amount of data you have provided is insufficient (mainly because there is too much difference between using postman from your development machine and app working on a android device - does it have enough ram? what exactly spans those 15 seconds - changes in the UI or it is time between http request and response? what does it mean they are on the same network? etc...).

BTW "https://MyWebsite.com/MyAPI.php/username/password" - passing username and password like this makes me uneasy in terms of security see: https://owasp.org/www-community/vulnerabilities/Information_exposure_through_query_strings_in_url#

Also, I'd strongly recommend using json parsing library instead of current solution like jackson object mapper (simple tutorial: https://www.baeldung.com/jackson-object-mapper-tutorial)

\$\endgroup\$
2
  • \$\begingroup\$ it might have been some time, but I took your advice and went through everything you suggested, I was able to figure out the delay problem, no longer passing the username & password through the URL (using headers with Base64 encryption) and learned how to use JSON to extract the data. Thank you very much. \$\endgroup\$
    – KiDo
    Nov 17 '21 at 12:34
  • \$\begingroup\$ Love to hear that first part, keep up the good work - but please note that Base64 is not an encryption - anyone having access can decode it, if you are communicating over https (and making sure of it) keeping secrets in headers is probably enough, no need to additionally encrypt them. In case of doubt refer to cheatsheetseries.owasp.org/cheatsheets/… and cheatsheetseries.owasp.org/cheatsheets/… and in general to OWASP materials. \$\endgroup\$
    – Azahe
    Nov 17 '21 at 13:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.