0

I am trying to get a JSON object using Volley to create a dynamic Auto complete, but on requesting using volley I see this in the log cat:

D/Volley: [486] BasicNetwork.logSlowRequests: HTTP response for request=<[ ] https://api.railwayapi.com/v2/suggest-train/train/2/apikey/xnlo6zq3yj/ 0x2538544 NORMAL 1> [lifetime=5648], [size=363753], [rc=200], [retryCount=0]

My problem was not solved by these answers.

Here is the Singleton Class which is initializing the Request queue:

import android.content.Context;

import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;

public class SingleTon {
    private Context context;
    private RequestQueue requestQueue;
    public static SingleTon singleTon;
    public SingleTon(Context context){
        this.context=context;
        requestQueue=getRequestQueue();
    }
    private RequestQueue getRequestQueue(){
        if(requestQueue==null){
            requestQueue= Volley.newRequestQueue(context);
        }
        return requestQueue;
    }
    public synchronized static SingleTon getInstance(Context context){
        if(singleTon==null){
            singleTon=new SingleTon(context.getApplicationContext());
        }
        return singleTon;
    }
    public void addToRequestQueue(Request request){
        requestQueue.add(request).setRetryPolicy(new DefaultRetryPolicy([I have tried all possible combinations here]));
    }
}

The method which is making the request:

public Filter getFilter() {
    Filter filter=new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence charSequence) {
            FilterResults filterResults=new FilterResults();
            if(charSequence!=null){
                String partialName=charSequence.toString();
                String url="https://api.railwayapi.com/v2/suggest-train/train/"+partialName+"/apikey/xnlo6zq3yj/";
                HTTPConnector httpConnector=new HTTPConnector(url,context);
                JSONObject response=httpConnector.getJsonResponse();
                try {
                    JSONArray trains=response.getJSONArray("trains");
                    for(int i=0;i<trains.length();i++){
                        trainName.add(new Train(trains.getJSONObject(i).getString("number")));
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                filterResults.values=trainName;
                filterResults.count=trainName.size();
            }
            return filterResults;
        }

Here is the HTTP Connector class:

package com.example.mukhe.dynamicautocomplete;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;

import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONObject;

/**
 * Created by mukhe on 06-Feb-18.
 */

public class HTTPConnector {
    String url;
    JSONObject jsonResponse;
    Context context;
    public HTTPConnector(String url,Context context){
        this.url=url;
        this.context=context;
    }

    public JSONObject getJsonResponse() {
        makeQuery();
        return jsonResponse;
    }
    private void makeQuery(){
        JsonObjectRequest request=new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                jsonResponse=response;
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(context,"ERROR",Toast.LENGTH_SHORT).show();
                Log.d("ERROR: ", error.toString());
            }
        });
        SingleTon.getInstance(context.getApplicationContext()).addToRequestQueue(request);
    }
}
Pronoy999
  • 645
  • 6
  • 25

1 Answers1

1

That is weird way you using Volley. Volley is makes Asyncronous HTTP Requests. Your these two lines will not give you results every time

 HTTPConnector httpConnector=new HTTPConnector(url,context);
 JSONObject response=httpConnector.getJsonResponse();

You are sending async.. request and calling getJsonResponse function immediately ? you can't sure about that a response is available when you are calling that function. You should return response when you got response i.e inside OnResponse method of JsonObjectRequest

So you should implement communication correctly between HTTPConnector Class and Class which contain getFilter method.

You can use interface for this. Inside your HTTPConnector Class declare interface and implement it on your Activity.

public class HTTPConnector {
    String url;
    JSONObject jsonResponse;
    Context context;
    IMyInterface  mListener;
    public interface IMyInterface
   {
    void sendResponse(JsonObject obj);
   }

    public HTTPConnector(String url,Context context,IMyInterface pListener){
        this.url=url;
        this.context=context;
        mListener=pListener
    }


    public void makeQuery(){
        JsonObjectRequest request=new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                jsonResponse=response;
             if(mListener!=null)
           {
            mListener.sendResponse(response);
           }
             }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(context,"ERROR",Toast.LENGTH_SHORT).show();
                Log.d("ERROR: ", error.toString());
               if(mListener!=null)
                {
                   mListener.sendResponse(null);
                }
            }
        });
        SingleTon.getInstance(context.getApplicationContext()).addToRequestQueue(request);
    }
}

In Your Activity, implement interface and override sendResponse method of interface.

public class MainActivity extends AppCompatActivity implements HTTPConnector.IMyInterface
{
  ...........
  ...........
  // Your other code of activity
  ...........
  ..........

  @Override
  public void sendResponse(JsonObject response)
  {
   try {
       JSONArray trains=response.getJSONArray("trains");
       for(int i=0;i<trains.length();i++){
                    trainName.add(new Train(trains.getJSONObject(i).getString("number")));
                }
               //Now you have response and filled the list, can call getFilter
            } catch (JSONException e) {
                e.printStackTrace();
            }

  }

}

Somewhere in your activity probably when you have query text for URL. make volley request like below.

String url="https://api.railwayapi.com/v2/suggest-train/train/"+partialName+"/apikey/xnlo6zq3yj/";
    HTTPConnector httpConnector=new HTTPConnector(url,context,this); // this will act as your listener
    httpConnector.makeQuery();
Zaid Mirza
  • 3,540
  • 2
  • 24
  • 40