Updating Content thru Volley at Time Intervals - android

I know there are multiple post on doing this, but with limited Android experience I am little confused as to who to believe. I have an app that loads content on start up from my server thru Volley request. After a period of time I want to make a Volley request back to update the content that is displayed to the user. When the app first loads, I determine the number of seconds from the half hour which I pass to the following
public static void refreshAllContent(final long timetoupdate) {
new CountDownTimer(timetoupdate, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
Log.i("SCROLLS ", "UPDATE CONTENT HERE ");
resetContent();
}
}.start();
}
On the finish it calls the refreshAllContent which is where I would make the Volley request and reset the count for the next update, I have something like
public static void resetContent(){
Handler handler= new Handler();
Runnable runnable= new Runnable() {
#Override
public void run() {
//PUT VOLLEY REQUEST HERE
refreshAllContent(Times. initialTime());
}
};
}
I guess I am stuck as to exactly how to make the Volley request, meaning what do I have to worry do this. Like I said not a lot of experience so not sure if I run the request in a special runnable or task. Any direction appreciated.
EDIT: I reworked this some, instead of going back to the refreshAllContent, I replaced this with
private static void resetContent(){
Log.i("SCROLLS ", "ENTER resetContent");
final Handler handler= new Handler();
Runnable runnableCode = new Runnable() {
#Override
public void run() {
refreshData(); // Volley Request
handler.postDelayed(runnableCode, 20000);
}
};
handler.post(runnableCode);
}
Logic is now on the initial run, the first timetoupdate is created and passed to the refreshAllContent. Once the countdown is complete, the resetContent() will run which makes the Volley Request in the refreshData(). Now I am getting an error stating the runnableCode needs to be declared final since it's accessed from an inner class, same for the handler. Well adding final to the
final Runnable runnableCode=new Runnable(){
line doesn't fix the error, I still have an error telling me the runnableCode has not been initialized. Can I get little help on this.

You don't create a Runnable to run Volly. Volly runs network calls on a background thread by default.
Here is a simple Volly code:
public void volleyProcess(){
RequestQueue requestQueue = Volley.newRequestQueue(this);
StringRequest request = new StringRequest(Request.Method.GET, "https://api.myjson.com/bins/753rt", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, response);
refreshAllContent(30000);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, error.toString());
}
});
requestQueue.add(request);
}
onResponse() is called when a response is successfully returned by the call. This method is called on the main thread therefore you can run your refreshAllContent() method here. and the parameter 'response' is the data returned, do what ever you want with it here(i am simply printing it to the Logcat).
Now to make this code run after the desired interval, just call it in onFinish() of the countdownTimer.
public static void refreshAllContent(final long timetoupdate) {
new CountDownTimer(timetoupdate, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
Log.i("SCROLLS ", "UPDATE CONTENT HERE ");
volleyProcess();
}
}.start();
}
Hope this helped

Related

How to Update UI inside volley response listener ? is runOnUiThread needed? or does Onresponse takes the control to UI Thread by itself?

while using volley library ,if i want to update the listview adapter inside Response listener , should it be done using runOnUiThread? or is it already in UiThread?
You may get the following exception when the adapter tries to modify view objects:
android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
So, just do the following to be on the safe side:
geyActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
adapter.notifyDataSetChanged();
}
});
call handler from volley response
#Override
public void onResponse(String response) {
Log.d("Response is: ", response);
rui = response; // i put response to public String variable rui
myHandler.post(updateRunnable);
parseJSON(response);
}
and in onCreate Activity
myHandler = new Handler();
updateRunnable = new Runnable() {
public void run() {
//call the activity method that updates the UI
updateUI();
}
};
and your update on updateUI
public void updateUI(){
t.setText(rui);
}
and make sure your id of widget is really existed.
<TextView
android:id="#+id/konten"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

Add waiting time to android asynchronous task

I have a Forgot Password screen. The user fills in his email, clicks on submit and an HTML request is submitted. It either returns the string "true" or "false". If it returns true, I would change the text on the screen, wait for 2 seconds and send the user to another page. Here's how I'm doing it
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if ("true".equals(response)) {
//make one TextView invisible and the other visible.
findViewById(R.id.pre_password_reset_text).setVisibility(View.INVISIBLE)
findViewById(R.id.post_password_reset_text).setVisibility(View.VISIBLE);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace;
}
startActivity(new Intent(ForgotPassword.this, Login.class));
} else {
//show error message
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//show error message
}
});
requestQueue.add(stringRequest);
The problem is, the thread goes to sleep for 2 seconds and after that the text-change happens. But, in the code I've written the text-change to happen first and then Thread.sleep.
What am I missing here?
Using Volley, the onResponse() code is called from the main thread, so calling Thread.sleep is definitelly forbidden because it would block the UI.
If you want to delay the call to the next activity, you need to defer it to a runnable, and delay it :
#Override
public void onResponse(String response) {
if ("true".equals(response)) {
//make one TextView invisible and the other visible.
TextView passwordView = (TextView) findViewById(R.id.pre_password_reset_text).setVisibility(View.INVISIBLE);
findViewById(R.id.post_password_reset_text).setVisibility(View.VISIBLE);
passwordView.postDelayed(new Runnable() {
public void run() {
startActivity(new Intent(ForgotPassword.this, Login.class));
}
}, 2000);
} else {
//show error message
}
}
A cleaner way would be to create a Handler in your Activity/Fragment and post the runnable on it, but it is simpler to directly use your password view.
Thread.sleep in main thread of your app isn't a good idea. You could use Android handlers to schedule a task in the future. Handlers will behave in an asynchronous message passing manner, so you don't freeze up your whole app during the wait period.
handler.postDelayed(new Runnable(){
#Override
public void run(){
// Start your new activity here!
}
}, 2000);
Note: All views and their derivations come with a built-in handler, so you wouldn't need to define a bare handler for this purpose.

Retrofit "IllegalStateException: Already executed"

I have a Retrofit network call that id like to run every 5 seconds. My current code:
Handler h = new Handler();
int delay = 5000; //milliseconds
h.postDelayed(new Runnable() {
public void run() {
call.enqueue(new Callback<ApiResponse>() {
#Override
public void onResponse(Response<ApiResponse> response) {
Log.d("api", "response: " + response.body().getPosition().getLatitude().toString());
}
#Override
public void onFailure(Throwable t) {
}
});
h.postDelayed(this, delay);
}
}, delay);
This runs once, but then throws the following:
java.lang.IllegalStateException: Already executed.
at retrofit2.OkHttpCall.enqueue(OkHttpCall.java:52)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.enqueue(ExecutorCallAdapterFactory.java:57)
at orbyt.project.MyFragment$1.run(MyFragment.java:93)
Whats the issue here?
As a bonus: whats a better way to handle this? Ill be updating a map every update. I was thinking about trying to use Rx but not sure if this is an appropriate use-case, or how to implement it.
A Call can only be used once. Its documentation tells you how to use one multiple times:
Use clone() to make multiple calls with the same parameters to the same webserver; this may be used to implement polling or to retry a failed call.
So use call.clone().enqueue(..) for Asynchornous and call.clone().execute() for Synchornous respectively to ensure that you have a fresh, unexecuted Call for each request.

Android: Cancel Volley request during execution due to slow connection

I'm using Volley in Android in order to make requests including fetching relatively large amount of data. I want to make timer of 5 seconds and if after it the request not returned - it probably means that there is slow connection and therefore I want to cancel the request. So far what I did:
Timer timer = new Timer();
VioozerVolleyRequestFactory mFactory = new VioozerVolleyRequestFactory(this);
RequestQueue mQueue = VioozerVolleySingleton.getInstance(this).getRequestQueue();
timer.schedule(new TimerTask() {
#Override
public void run() {
mQueue.cancelAll("MY_TAG");
}
}, 5000};
Request<String> request = mFactory.createRequest(RequestType,
new Listener<String>() {
#Override
public void onResponse(String response) {
timer.cancel();
//...
}
},
new ErrorListener<String>() {
#Override
public void onErrorResponse(String response) {
timer.cancel();
//...
}
}, extra);
request.setTag("MY_TAG");
mQueue.add(request);
My question: It seems that the request not canceled. The request is executed so the build in method cancelALL(TAG) not relevant here. How can I still achieve my requirement?
Thanks,
By default Volley request timeout is set to 2500ms and it makes 1 retry per request.
You need to override DefaultRetryPolicy of Request.
for example:
Wait for 5000ms and do not perform any retry.
request.setRetryPolicy(new DefaultRetryPolicy(5000,0,1f));
Ref: DefaultRetryPolicy.java

Display message on non-stop thread

Following code is within an android activity class.
The project required a non-stop thread when apps is active and stop when apps is inActive/closed.
I predicted to see a non-stop "Hello World" message display in logCat.However I only saw one-times Hello World messgae .
What wrong of my code,so that I able to see a non-stop "Hello World"
Hope someone advice. Thanks
#Override
protected void onStart(){
super.onStart();
Log.e("onStart","beforeStart");
new HttpRequestTask().execute();
Log.e("onStart","Start");
this.pickButtonThread();
}
private void pickButtonThread(){
new Thread() {
#Override
public void run() {
try {
// code runs in a thread
PickerItemActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// code runs in a UI(main) thread
//isPickButtonEnableDisable();
//new HttpRequestTask().execute();
Log.e("pickButtonThread", "Hello World");
}
});
} catch (final Exception ex) {
}
}
}.start();
}
That's because you don't have any loop inside your run() method, thus it's run just once and it exits. However, declaring an endless loop is not considered a good idea as Android OS might kill it if there's lack of memory.
You could use a Handler using the .postDelayed() method to post messages every X seconds.
private Handler mHandler = new Handler();
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
Log.e("pickButtonThread", "Hello World");
mHandler.postDelayed(this, 1000); // Every second
}
};

Categories

Resources