Refreshing the activity - android

i am making the app in which user will be able to c the routine services available to him . For this i am using the website where the admin will be able to update the services . User from android will be able to get the list of services by parsing the xml file available on the server .
The thing i am wondering about is that is there any way the activity automatically refresh itself and user can c the updates done in the services by admin.
Thanks

If you need to do some job on a regular basis, you should have a look at the Handler and the AsyncTask. The general scheme is the following:
//This handler launches the task
private final Handler handler = new Handler();
//This is a task which will be executed
private class RefreshTask extends AsyncTask<String, Void, Object> {
protected Object doInBackground(String... params) {
//Do refreshing here
}
protected void onPostExecute(Object result) {
//Update UI here
}
}
//This is a Runnable, which will launch the task
private final Runnable refreshRunnable = new Runnable() {
public void run() {
new RefreshTask(param1, param2).execute();
handler.postDelayed(refreshRunnable, TIME_DELAY);
}
};
Then you call handler.post(refreshRunnable) when you want to start updates. To cancel them, call handler.removeCallbacks(refreshRunnable). I should note, of course, that I haven't tested this code, but it should give a general idea what to do.

Related

Asynctask and queue OR delay in execution

Scenario:
The user has a list of items, let's say 10 items. Each item has an Operation button, which calls an AsyncTask which makes a web call. When a call is made, the item displays a spinner during the execution of the task
Problem:
Some of the users abuse this, and press quickly more Operation buttons, quicklt one after another, executing the web calls too often. So I want to be able to somehow, execute each of the AsyncTasks one after another with a delay of 2 seconds between executions. I do not want to switch to something else from AsyncTask if possible. So basically if there are 3 Operation buttons pressed, the execution should be:
-> Operation 1
-> 2 seconds delay
-> Operation 2
-> 2 seconds delay
-> Operation 3
-> ....
What would be the best way to do this in Android?
LE:
I have just realized something, for executing my task I ran the following code:
myTask = new MyTask();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
myTask.execute();
}
Well, I've been using this code for a lot of time now, knowing that after honeycomb the tasks were not executed in parallel anymore without using an Executor. So it seems that only doing a simple myTask.execute() and adding a Thread.sleep() makes my AsyncTasks execute, one after another just as expected.
You will need to maintain a list of the operations that needs to be performed.
on click of the button add the task in the list, call a method which check the list for the task and executes it if there is no other task is running..
in onPostExecute method call the same method to check if there is any other task / operation that needs to be performed..
It may not be the full code you require... but may give you some idea..
public class TestActivity extends AppCompatActivity {
private static boolean isTaskRunning =false;
static ArrayList<CustomTask> customTaskList = new ArrayList();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
}
public void onBtnClick(View view)
{
// create custom task with required values and actions
CustomTask customTask = new CustomTask();
customTaskList.add(customTask);
checkAndExecuteTask();
}
private static void checkAndExecuteTask()
{
//checks if there is any task in the list and is there any other running task
if(customTaskList.size()>0 && !isTaskRunning) {
new MyAsync(customTaskList.get(0)).execute();
}
}
static class MyAsync extends AsyncTask<Void,Void,Void>
{
CustomTask currentCustomTask;
public MyAsync(CustomTask customTask)
{
currentCustomTask = customTask;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
isTaskRunning= true;
}
#Override
protected Void doInBackground(Void... voids) {
// do your stuff
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
customTaskList.remove(currentCustomTask);
isTaskRunning =false;
checkAndExecuteTask(); // task is completed so check for another task and execute (if any).
}
}
class CustomTask
{
// create class with required fields and method
}
}
There are a number of ways you can do this in android.
One way is to use a handler.
What you need to do is to, create a seperate thread and run handler.postDelayed in it.
private void startWebCall() {
Thread thread = new Thread() {
public void run() {
Looper.prepare();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Do your web calls here
handler.removeCallbacks(this);
Looper.myLooper().quit();
}
}, 2000);
Looper.loop();
}
};
thread.start();
}
You should call above method whenever user clicks a item.
Another way that I can think of is using an IntentService
An IntentService is a service that is used for doing asynchronous tasks in background. It maintains a queue of the tasks it needs to do. It is different from the above approach in the sense that it executes these tasks in a sequential order. So when you make requests to it to make web calls it will queue them, make the first call and then after it finishes it will make the second call. So the different web calls will not execute in parallel. They will execute in a sequential order but in a different thread. Also it is a service so it can run even in the background, i.e if user closes the app.
This is a good tutorial to get start with IntentService.
AsyncTaks should be generally avoided unless the work one needs to do is quite trivial. This blog explains its pitfalls.

How to work with AsyncTask and threads?

The goal:
Using Google App Engine server and Android client, I'm trying to put on the Google map at the Android client Users overlays. Every 30 seconds I'm polling the server and getting Vector that contains users and adding it to the map.
Current status:
I'm dong all that using in one new thread, So after running the app I got:
weird behaviors(delayed overlays, multiple overlays) and after that crushed with ConcurrentModificationException.
After reading a bit i figured out that I need to work with AsyncTask.
Correct me if I'm wrong,But I understand that everything done in the Activity at at onCreate is "running" in UIhread so I need to put the "Logic" (All the Network handling) in doInBackground and all the UI Handling like putting overlays on the map in onPostExecute.
My Question are:
1) In the current status I'm doing:
new Thread()
{
#Override
public void run()
{
super.run();
while(true)
{
SystemClock.sleep(30000);
Vector responseFromServer = getUsersVectorFromServer();
putNewOnlineUserOnTheMap();
}
}
}.start();
What is the right way to convert this To AsyncTask?
Do I poll the server still using new thread in the doInBackground or there is right way to do this?
2) Is there a specific list of what counts as UI to put in onPostExecute or any concepts list?
In my case I guess that in need to put putNewOnlineUserOnTheMap() in onPostExecute.
Thanks.
Something similar to the following:
class UpdateTask extends AsyncTask<Void, Vector, Void>{
#Override
protected Void doInBackground(Void... params) {
// this is running in a background thread.
while (!isCancelled()) {
SystemClock.sleep(30000);
Vector responseFromServer = getUsersVectorFromServer();
// send the result back to the UI thread
// onProgressUpdate will be called then
publishProgress(responseFromServer);
}
return null;
}
#Override
protected void onProgressUpdate(Vector... values) {
// this is executed on the UI thread where we can safely touch UI stuff
putNewOnlineUserOnTheMap(values[0]);
}
}
You can't use the result of the task since the task is finished then. But you can use the progress publishing mechanism to get periodic results. If you use it like that and do the modification on the UI thread you should not get ConcurrentModificationException because you do the modifications on the one thread that can safely modify the UI.
One thing to note here: create new instances of your Vector in the background thread and then use it to update the UI. But don't touch the same object afterwards in the backgroundthread. That way you don't need any synchronization since after the background thread sends it away it is only the UI thread that touches it. (and you could use a simple ArrayList instead of a Vector)
AsyncTask uses generics and varargs.The parameters that are passed to the asyntask are . TypeOfVariableArgumentsParameters is passed into the doInBackground(), ProgressParam is used for progress information and ResultParam must be returned from doInBackground() and is passed to onPostExecute() as parameter.
example:--
protected class ParsingTask extends AsyncTask> {
private ProgressDialog loadingDialog = new ProgressDialog(JsonParserActivity.this);
protected void onPreExecute() {
loadingDialog.setMessage("loading app store..");
loadingDialog.show();
}
#Override
protected ArrayList<Items> doInBackground( Context... params ) {
// do ur process here.
return result;
}
if (!this.isCancelled()) {
}
return result;
}
#Override
protected void onProgressUpdate(String... s) {
super.onProgressUpdate(s);
Toast.makeText(getApplicationContext(), s[0], Toast.LENGTH_SHORT).show();
}
#Override
protected void onPostExecute( ArrayList<Items> response ) {
//if u r dealing with list view and adapters set the adapter here at the onPostExecute()
loadingDialog.dismiss();
}
#Override
protected void onCancelled() {
super.onCancelled();
Toast.makeText(getApplicationContext(), "The operation was cancelled", 1).show();
}
}
You can use AsyncTask like below. Hope this will help you..
Class YourClass{
void YourClass(){
NetworkTask nT = new NetworkTasK();
nT.execute();
}
}
protected class NetworkTask extends AsyncTask<Void, String, Boolean>
{
#Override
protected Boolean doInBackground(Void... params)
{
try
{
String response;
while(keepreceiving)
{
response = in.readLine();//Prog Counter stops here until getting i/p.
if(response != null)
yourFunctionForResponse(response);
}
}
catch (Exception ex)
{
}
return null;
}
private void yourFunctionForResponse(String response){
//things to do....
}
}
You may also try runOnUiThread(Runnable action) along with this to implement your work.

Android: Implication of using AsyncTask to make repeated Ajax Calls

I need my Android app to periodically fetch data from a server using AJAX calls, and update the UI accordingly (just a bunch of TextViews that need to be updated with setText()). Note that this involves 2 tasks:
Making an AJAX call, and updating the UI once I receive a response - I use a simple AsyncTask for this.
Doing the above repeatedly, at regular intervals.
I haven't figured out an elegant way to achieve Point 2 above. Currently, I am simply executing the task itself from OnPostExecute(). I read on this thread at SO that I need not worry about garbage collection as far as the AsyncTask objects are concerned.
But I'm still unsure as to how I set up a timer that will fire my AsyncTask after it expires. Any pointers will be appreciated. Here is my code:
public class MyActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new AjaxRequestTask().execute(MY_REST_API_URL);
}
private void updateReadings(String newReadings) {
//Update the UI
}
class AjaxRequestTask extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... restApiUrl) {
//Do AJAX Request
}
#Override
protected void onPostExecute(String result) {
updateReadings(result);
/*Is there a more elegant way to achieve this than create a new AsyncTask object every 10 seconds? Also, How can I update the UI if I create a timer here? */
new AjaxRequestTask().execute(MY_REST_API_URL);
}
}
}
Thanks in advance
EDIT:
I tried posting an answer but couldn't do it since I don't have the reputation to answer within 8 hours.
Well, so I found a solution. I'm not convinced however.
protected void onPostExecute(String result) {
updateReadings(result);
// super.onPostExecute(result);
new Timer().schedule(
new TimerTask() {
#Override
public void run() {
new AjaxRequestTask().execute(MY_REST_API_URL);
}
},
TIMER_ONE_TIME_EXECUTION_DELAY
);
}
Are there any flip sides that I should be aware of when I use this? In particular, I am seeing lots of GCs happening in the LogCat. Also, I am wondering how an AsyncTask can be candidate for GC unless the onPostExecute() completes?
How can I "stop" the updates? One way I thought of was to make the very first AsyncTask instance as a member variable of the Activity. That way, I can invoke cancel(true) on it and hope that this will "stop" the tasks.
SOLUTION:
In case anyone is looking for something similar - none of the solutions I mentioned here work satisfactorily. They all suffer from OutOfMemory issues. I did not debug into the details of the OOM, but I suspect it could either be because of the recursion, or because of having HTTP-related objects as member variables in the AsyncTask rather than as members of the Activity (basically because of NOT reusing HTTP and other objects).
I discarded this approach for a different one - making my Ajax Calls endlessly in the doInBackground() of my AsyncTask; and updating the UI in onProgressUpdate(). That way I also avoid the overhead of maintaining too many threads or Handlers for updating the UI (remember UI can be updated in onProgressUpdate() ).
This approach also eliminates the need for Timers and TimerTasks, favoring the use of Thread.sleep() instead. This thread on SO has more details and a code snippet too.
Call postDelayed() on any View to schedule a hunk of code to be run on the main application thread after a certain delay. Do this in onPostExecute() of the AsyncTask to create and execute another AsyncTask.
You could use AlarmManager, as others have cited, but I would agree with you that it feels a bit like overkill for timing that occurs purely within an activity.
That being said, if the AJAX calls should be occurring regardless of whether the activity exists, definitely consider switching to AlarmManager and an IntentService.
I think the android way to do this is using AlarmManager. Or you can user a basic java Timer as well. I'd recommend AlarmManager.
Set it up to send some intent with a custom Action, and register a broadcastreceiver for it.
If the ajax calls are only executed in the activity you can just use a timer in the activity which starts the tasks.
Otherwise use a service which uses the AlarmManager and which connects to the gui via a broadcast.
The recommended way to do a repeated task, is via AlarmManager, as alluded to by Scythe. Basically it involves setting up a broadcast listener, and having AlarmManager fire off an intent to that listener at whatever interval you choose. You then would have your broadcast listener call out to the activity to run the AsyncTask. If you need a very tight timer (less than 5s calls I'd say), then you're better off using a Timer within a Service, and using AIDL to call back to the activity.
Instead of talking directly from the broadcast intent, you could also setup an IntentService which you can poke, and use AIDL to update the activity.
This is how I achieved it finally. Note that the AsyncTask cancel(true) method is useless in my scenario because of the recursion. I used what #CommonsWare suggested - used a flag to indicate whether any more tasks should be executed.
public class MyActivity extends Activity {
/*Flag which indicates whether the execution should be halted or not.*/
private boolean mCancelFlag = false;
private AjaxRequestTask mAjaxTask;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if(mAjaxTask == null){
mAjaxTask = new AjaxRequestTask();
}
mAjaxTask.execute(MY_REST_API_URL);
}
#Override
protected void onResume() {
super.onResume();
mCancelFlag = false; /*when we resume, we want the tasks to restart. Unset cancel flag*/
/* If the main task is Finished, create a new task and execute it.*/
if(mAjaxTask == null || mAjaxTask.getStatus().equals(AsyncTask.Status.FINISHED)){
new AjaxRequestTask().execute(TLS_REST_API_URL);
}
}
#Override
protected void onPause() {
mCancelFlag = true; /*We want the execution to stop on pause. Set the cancel flag to true*/
super.onPause();
}
#Override
protected void onDestroy() {
mCancelFlag = true;/*We want the execution to stop on destroy. Set the cancel flag to true*/
super.onDestroy();
}
private void updateReadings(String result) {
//Update the UI using the new readings.
}
class AjaxRequestTask extends AsyncTask<String, Integer, String> {
private AjaxRequestTask mChainAjaxRequest;
private Timer mTimer;
private TimerTask mTimerTask;
#Override
protected String doInBackground(String... restApiUrl) {
//Do AJAX call and get the response
return ajaxResponse;
}
#Override
protected void onPostExecute(String result) {
Log.d(TAG, "Updating readings");
updateReadings(result);
// super.onPostExecute(result);
if(mTimer == null){
mTimer = new Timer();
}
if(!mCancelFlag){/*Check if the task has been cancelled prior to creating a new TimerTask*/
if(mTimerTask == null){
mTimerTask = new TimerTask() {
#Override
public void run() {
if(!mCancelFlag){/*One additional level of checking*/
if(mChainAjaxRequest == null){
mChainAjaxRequest = new AjaxRequestTask();
}
mChainAjaxRequest.execute(MY_REST_API_URL);
}
}
};
}
mTimer.schedule(mTimerTask,TIMER_ONE_TIME_EXECUTION_DELAY);
}
}
}
}

Need to show loading screen while app queries server

in this app, the user logs in and their credentials are checked against a server.
The user could be waiting a few seconds, depending on how fast the phone can open a data connection if at all. I need dialog box saying "please wait" or "verifying credentials" or something a long those lines after the user clicks log in.
Desired visual order: press log in -> "please wait" dialog is show in this same activity -> when result comes in from server a new activity is loaded (or error is thrown)
Current visual order: press log in -> user waits as if the app is frozen -> new activity is loaded
I'm trying to do this threading thing with AsyncTask but I'm just not getting it right now!
class Progressor extends AsyncTask<Void, Void, Void> {
ProgressDialog dialog;
protected void onPreExecute(){
dialog = ProgressDialog.show(Login.this, "Logging In",
"Verifying Credentials, Please wait...", true);
}
Then in my oncreate method I had all of the other logic like user clicking the button and stuff, but I've since moved that into the AsyncTask method's doInBackGround function
/* When the Login Button is clicked: */
Button loginButton = (Button) findViewById(R.id.loginButton);
loginButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Progressor showMe = new Progressor();
showMe.onPreExecute();
showMe.doInBackground(null);
showMe.onPostExecute();
and onPostExecute simply dismisses the dialog box
Why doesn't this work and how should it be re-arranged. What variable should I be passing into the showMe.doInBackGround() function, it is void. In debugging it never goes in here
#Override
protected Void doInBackground(Void... arg0) {
Don't call the onPreExecute/doInBackground methods of an AsyncTask manually; just call execute() on it and it will call all your methods in the proper places from the correct threads. It defeats the entire purpose of an asynchronous task to call all of its methods synchronously from the UI thread (which is what your sample code does).
That isn't how you use an AsyncTask, have a look at the documentation. Once you have created a new instance of your task, just call execute(), not the individual methods:
Progressor showMe = new Progressor();
showMe.execute();
I have a similar code at the start of my application i load the current settings from the server, it works for me with:
public static ProgressDialog verlauf;
public static String vmessage = "";
static Handler handler = new Handler();;
public static void initialize_system(final Context ctx)
{
verlauf = ProgressDialog.show(ctx, "Starte FISforAndroid..", "synchronisiere Einstellungen",true,false);
new Thread(){
#Override
public void run(){
Looper.prepare();
GlobalVars.table_def.initialize();
vmessage = "erstelle Tabellen";
handler.post(verlauf_message);
builded = sqldriver.create_tables();
vmessage = "setze Systemkonstanten";
handler.post(verlauf_message);
builded = setsystemvars(ctx);
vmessage = "synchronisiere Einstellungen";
handler.post(verlauf_message);
builded = settings.sync_ini();
builded = settings.set_ini();
GlobalVars.system_initialized = builded;
switch(GlobalVars.init_flags.FLAG){
case 0:
break;
case GlobalVars.init_flags.UPDATE:
//load the update
break;
}
verlauf.dismiss();
}
}.start();
}
You need to call showMe.execute(), rather than directly calling doInBackground or onPreExecute etc.

How to use separate thread to perform http requests

I have an application that is performing HTTP Requests (specifically calling the FogBugz API) when the user clicks certain buttons. Right now, I am just creating a service when the application starts, and then calling different methods in that service to complete requests. However, when I do this, there is the usual hang in the UI thread. I have looked at AsyncTask, but am not sure it will do what I want to accomplish. Because I need to instantly parse the XML that the HTTP Request returns, I need to have a process that is able to return this data to the UI thread. Will ASyncTask be able to accomplish this, or is there some other way?
public static InputStream makeRequest(String httpRequest)
{
In a separate thread, run HTTP Request, get back and process, return inputstream
}
This method is called by several others to perform HttpRequests. Once the inputstream is returned, the other methods parse for specific information.
The simplest way to do it would just be to do something like
//Body of your click handler
Thread thread = new Thread(new Runnable(){
#Override
public void run(){
//code to do the HTTP request
}
});
thread.start();
That will cause the code inside the run() method to execute in a new thread of execution. You can look into an async task if you like although I've personally never used it. This is a quick and simple way to get things done.
With regards to passing information back, I would use a Handler object which effectively allows you to set up a message queue for a given thread and pass messages to it which cause the execution of specific code. The reason you need to do this is because Android will not let any thread other than the UI thread update the actual UI.
Does that address your question? I know my first pass didn't fully address all of your issues.
Edit Basically, what you do is define a handler object in your Activity like
private Handler handler_ = new Handler(){
#Override
public void handleMessage(Message msg){
}
};
You also create static int constants that help tell the handler what to do. You basically use those to allow for several different types of messages to be passed to one instance of a handler. If there is only going to be one message that is passed back, then you don't have to worry about that.
For example
private static final int UPDATE_UI = 1;
To send a message to the handler you call
handler_.sendMessage(Message.obtain(handler_, UPDATE_UI, inputStreamInstance));
From the handler:
private Handler handler_ = new Handler(){
#Override
public void handleMessage(Message msg){
switch(msg.what){
case UPDATE_UI:
InputStream is = (InputStream)msg.obj;
//do what you need to with the InputStream
break;
}
}
};
Alternatively, where the inputStreamInstance is added to the Message object, you can pass any object you like so if you wanted to parse it into some kind of container object or something like that, you could do that as well. Just cast it back to that object from within the handler.
Try using AsyncTask. Goto this Link for more:
private class SyncIncoData extends AsyncTask<String, String, String> {
ProgressBar pb;
ProgressBar pbar;
#Override
protected String doInBackground(String... urls) {
for (int i = 0; i <= 100; i++) {
publishProgress(i);
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pb = (ProgressBar) findViewById(R.id.progressBarsync4);
pb.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(String result) {
pb = (ProgressBar) findViewById(R.id.progressBarsync4);
pb.setVisibility(View.INVISIBLE);
}
#Override
protected void onProgressUpdate(String... values) {
pbar = (ProgressBar) findViewById(R.id.progressBarpbar);
pbar.setProgress(Integer.parseInt(values[0]));
super.onProgressUpdate(values);
}
}
Write the program for http request inside doinbackgroud()

Categories

Resources