I'm using getConnection method in my program and I want to restore the response in a variable like "String result " in-order to use in another class, but I don't know how I must change the method. Does anyone have an idea?.
public class Webservice {
public static void getConnection(Context context, String url){
RequestQueue queue = Volley.newRequestQueue(context);
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("TEST", "Response is: "+ response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("TEST","That didn't work!");
}
});
queue.add(stringRequest);
}
}
You can create a variable in Application class and use it throughout your application like this
public class App extends android.app.Application {
private static App instance;
public static String resultResponse;
public static App getInstance() {
return instance;
}
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
}
Then when you get the response save it like this
public class Webservice {
public static void getConnection(Context context, String url){
RequestQueue queue = Volley.newRequestQueue(context);
StringRequest stringRequest = new StringRequest(Request.Method.GET,
url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("TEST", "Response is: "+ response);
App.getInstance().resultResponse = response;
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("TEST","That didn't work!");
}
});
queue.add(stringRequest);
}
}
Add
android:name = ".App"
in Application in your manifest.
Now Use
App.getInstance().resultResponse
where ever you want through out your Application.
You can use interface having return type String in onResponse method and implement this interface in your required class get String response.
Related
I need to call an api to get a json data using android volly. I have a method implemented inside class A to call the get request as shown
class A{
public static String getList(Context context,String url)
{
final String[] result = new String[1];
JsonArrayRequest req = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.e("response",response.toString());
result[0] =response.toString();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("responseerror",error.toString());
result[0] =error.toString();
}
});
MySingleton.getInstance(context).addToRequestQueue(req);
return result[0];
}
}
Inside class B i am accesing this method
class B {
String responce= A.getList(activity,url);
}
Here i can pass the context and url to get json data. But the problem is getList() method ruturs result even before it gets any response from the server. The app have more than one class which needs to call get request. If i will use this code snippet inside every such class then it will be against DRY principle. So what is the proper procudure to follow in this scenario?
Use an interface like below.
class A {
private final WeakReference<ResponseListener> responseListenerWeakRef;
public A(ResponseListener responseListener) {
responseListenerWeakRef = new WeakReference<ResponseListener>(responseListener);
}
public String getList(Context context, String url) {
JsonArrayRequest req = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.e("response",response.toString());
if (responseListener!=null && responseListener.get()!=null) {
responseListener.get().onResponse(response.toString());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("responseerror",error.toString());
if (responseListener!=null && responseListener.get()!=null) {
responseListener.get().onResponse(error.toString());
}
}
}
);
MySingleton.getInstance(context).addToRequestQueue(req);
}
public interface ResponseListener {
void onResponse(String response);
}
}
class B implements A.ResponseListener {
private void makeApiCall() {
new A(this).getList(activity, url);
}
#Override
public void onResponse(String response) {
// Do something with the response.
}
}
So I've run into a problem in my code, where I need to get a JSONString from my server with volley. And then I have to parse the String into a JSONObject and then continue doing stuff with that.
My problem here is, that Volley gives the response too late, meaning my string that I want to parse is always empty because its not initialised yet.
RequestFuture<String> future = RequestFuture.newFuture();
StringRequest stringRequest = new StringRequest(Request.Method.GET, searchURLBuilder, future, future);
// new Response.Listener<String>() {
// #Override
// public void onResponse(String response) {
// writeToSharedResponse(response_for_search, response);
// }
// },
// new Response.ErrorListener() {
// #Override
// public void onErrorResponse(VolleyError error) {
// Log.d("Error!!:" + error.getMessage(), "");
// }
// });
requestQueue.add(stringRequest);
String response = "";
try {
response = future.get(60, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
String responseString = m.getString(response_for_search, new String());
pieceDTOList = getPiecesDTOFromJSON(responseString);
Here is a snippet of my code. As you can see I already tried to make a "future" call to block and wait for the answer, but it just times out every time. The commented out bit, is the part I actually wanted to use from the beginning, but that returns the response to late. Since its asynchronous and accesses the server w/e it wants.
writeToSharedResponse just writes the answer into a sharedPreferences variable.
private SharedPreferences m;
private SharedPreferences.Editor editor;
private RequestQueue requestQueue;
public DbParser(Context c) {
m = PreferenceManager.getDefaultSharedPreferences(c);
editor = m.edit();
requestQueue = Volley.newRequestQueue(c);
}
My Question here is: Is there an easy way I can "wait" for the answer from volley so I can continue to work with the response that I get?
Edit 1:
I now added an interface and changed the code around to this:
getString(new VolleyCallback() {
#Override
public void onSuccess(String result) {
getPiecesDTOFromJSON(result);
}
}, searchURLBuilder);
return globalPieceDTOList;
}
private void getString(final VolleyCallback callback, String searchUrl){
StringRequest stringRequest = new StringRequest(Request.Method.GET, searchUrl,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
callback.onSuccess(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error!!:" + error.getMessage(), "");
}
});
requestQueue.add(stringRequest);
}
Since I cant get the values out of my inner classes, I did a nasty hack and created a global list for my DTO's. The problem now is that "return globalPieceDTOList" is always Null. And again - I would need to "wait" for the Volley response.
Volley requests are async, so when you try to return a value, the request is likely not done yet. If you want to return values from a Volley request use callback interfaces.
Example
public void getString(final VolleyCallback callback) {
StringRequest strReq = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// do some things here
callback.onSuccess(<PASS STRING RESULT HERE>);
}
});
}
public interface VolleyCallback{
void onSuccess(String result);
}
Example usage:
public void onResume(){
super.onResume();
getString(new VolleyCallback(){
#Override
public void onSuccess(String result){
//do stuff here with the result from the volley request
}
});
}
I am trying to get the number of "replies" or length of a response from the network here is my request below.
public class Replies {
private String questionId;
private VolleySingleton mVolleySingleton;
private RequestQueue mRequestQueue;
public int replies;
private String url;
//Predondition:Place the id of the questions into the constructor
//as well as the url
//Postcondition: counts the number of replies
public Replies(String questionId) {
this.questionId = questionId;
JsonRequestMethod();
}
public void JsonRequestMethod() {
url = "sampleURl"
mVolleySingleton = VolleySingleton.getInstance();
mRequestQueue = mVolleySingleton.getRequestQueue();
JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET,url, (String) null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
replies=response.length();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error);
}
});
mRequestQueue.add(request);
}
public String getReplies() {
return replies+"";
}
}
Also, in my adapter i have in my on bindviewholder this line of code
Replies replies=new Replies(currentSearch.getId());
holder.replies.setText(replies.getReplies());
However, it keeps getting set to 0 because its not waiting for the response, and the response is not 0. How do i fix this?
Maybe you can
public class Replies {
...
private NetWorkFinishListener listener;
void setListener(NetWorkFinishListener listener){
this.listener = listener;
}
public interface NetWorkFinishListener{
void onSuccess(int replies);
void onFailed(VolleyError error);
}
JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET,url, (String) null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
replies=response.length();
if(listener != null){
listener.onSuccess(replies);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error);
if(listener != null){
listener.onFailed(error);
}
}
});
}
And
Replies replies=new Replies(currentSearch.getId());
replies.setListener(new NetWorkFinishListener() {
#Override
public void onSuccess(int replies) {
holder.replies.setText(replies.getReplies());
}
#Override
public void onFailed(VolleyError error) {
// do some thing
}
});
//holder.replies.setText(replies.getReplies());
But there is a bug.
Holder may not be the original.But the listener still run Success().
you can use view.setTag() to judge.
I want to pass a response outside of my classes (many classes)
public static void userLocation()
{
RequestQueue queue = Volley.newRequestQueue(context);
String url = "http://www.jobdiagnosis.com/iphone/userlocation.php";
StringRequest dr = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
// response
//Toast.makeText(context, ""+response, Toast.LENGTH_LONG).show();
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
// error.
// Toast.makeText(getApplicationContext(), "error"+error, Toast.LENGTH_LONG).show();
Log.d("error", ""+error);
}
}
);
queue.add(dr);
}
Please suggest how I can pass a response outside of the class
In volly its difficult to return response outside the class.because request on server run in background and if we return value followed by queue.add(url) then it will return null.So there is no solution till now.Thanks!!
I watched the google io ,and saw volley. But I don't know how to get start with it.
I've tried to clone https://android.googlesource.com/platform/frameworks/volley , but the test project keep warn me "resource directory does not exist" .
please give me some clue!
Set up the project as a library ( Project->Properties->Android->"Is Library" ).
Then, just create the res folder in Volley project, and eclipse will build the Volley.jar !
I found this to get start with.
I write this Test Project , and import com.android.volley and com.android.volley.toolbox from the volley library. And it works ^_^
protected static final String TAG = "com.gyh.myvolleytest";
public static final String url = "http://192.168.1.108:8080/httptest/servlet/mainservlet?name=stack&age=23";
public static Response.ErrorListener createErrorListener() {
return new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Error Response code: " + error.getMessage());
}
};
}
public static Response.Listener<String> createSuccessListener() {
return new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// TODO parse response
String string = response.toString();
Log.d(TAG, "string :" + string);
}
};
}
public static Response.Listener<JSONObject> createJsonListener() {
return new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
String jsonStr = response.toString();
Log.d(TAG, "jsonStr :" + jsonStr);
System.out.println(jsonStr);
}
};
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void click(View view) {
RequestQueue queue = Volley.newRequestQueue(this);
// JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET,
// url, null, createJsonListener(), createErrorListener());
StringRequest request = new StringRequest(Request.Method.GET, url,
createSuccessListener(), createErrorListener());
queue.add(request);
queue.start();
}
Hope this can help ^_^