How to execute Async task repeatedly after fixed time intervals - android

How to make Async task execute repeatedly after some time interval just like Timer...Actually I am developing an application that will download automatically all the latest unread greeting from the server and for that purpose I have to check for updates from server after some fixed time intervals....I know that can be easily done through timer but I want to use async task which I think is more efficient for android applications.

public void callAsynchronousTask() {
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
PerformBackgroundTask performBackgroundTask = new PerformBackgroundTask();
// PerformBackgroundTask this class is the class that extends AsynchTask
performBackgroundTask.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 50000); //execute in every 50000 ms
}

//Every 10000 ms
private void doSomethingRepeatedly() {
Timer timer = new Timer();
timer.scheduleAtFixedRate( new TimerTask() {
public void run() {
try{
new SendToServer().execute();
}
catch (Exception e) {
// TODO: handle exception
}
}
}, 0, 10000);
}

You can just a handler:
private int m_interval = 5000; // 5 seconds by default, can be changed later
private Handle m_handler;
#Override
protected void onCreate(Bundle bundle)
{
...
m_handler = new Handler();
}
Runnable m_statusChecker = new Runnable()
{
#Override
public void run() {
updateStatus(); //this function can change value of m_interval.
m_handler.postDelayed(m_statusChecker, m_interval);
}
}
void startRepeatingTask()
{
m_statusChecker.run();
}
void stopRepeatingTask()
{
m_handler.removeCallback(m_statusChecker);
}
But I would recommend you to check this framework: http://code.google.com/intl/de-DE/android/c2dm/ Is a different approach: the server will notify the phone when something is ready (thus, saving some bandwidth and performance:))

wouldn't it be more efficient to create a service and schedule it via Alarm Manager?

The accepted answer is problematic.
Using TimerTask() for activating async task via handler is a bad idea. on orientation change you must remember to cancel also the timer and the handler calls. if not it will call the async task again and again on each rotation.
It will cause the application to blow up the server (if this is rest http get request) instead of X time - eventually the calls will be instance many calls on each second. (because there will be many timers according to the number of screen rotations). It might crush the application if the activity and the task running in background thread are heavy.
if you use the timer then make it a class memebr and cancel it onStop():
TimerTask mDoAsynchronousTask;
#Override
public void onStop(){
super.onStop();
mDoAsynchronousTask.cancel();
mHandler.removeCallbacks(null);
...
}
public void callAsynchronousTask(final boolean stopTimer) {
Timer timer = new Timer();
mDoAsynchronousTask = new TimerTask() {
#Override
public void run() {
mHandler.post(new Runnable() {
...
Instead try to avoid async task, and if you must then use scheduler service to run the async task. or the application class such as in this nice idea:
https://fattybeagle.com/2011/02/15/android-asynctasks-during-a-screen-rotation-part-ii/
Or use simple handler (without the timer, just use postDelayed) and also good practive is to call cancel the async task onStop(). this code works fine using postDelayed:
public class MainActivity extends AppCompatActivity {
MyAsync myAsync = new MyAsync();
private final Handler mSendSSLMessageHandler = new Handler();
private final Runnable mSendSSLRunnable = new Runnable(){
..
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
mSendSSLMessageHandler.post(mSendSSLRunnable);
}else
..
#Override
public void onStop(){
super.onStop();
if ( progressDialog!=null && progressDialog.isShowing() ){
progressDialog.dismiss();
}
mSendSSLMessageHandler.removeCallbacks(mSendSSLRunnable);
myAsync.cancel(false);
}
private final Runnable mSendSSLRunnable = new Runnable(){
#Override
public void run(){
try {
myAsync = new MyAsync();
myAsync.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
}
mSendSSLMessageHandler.postDelayed(mSendSSLRunnable, 5000);
}
};
class MyAsync extends AsyncTask<Void, Void, String> {
boolean running = true;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show
(MainActivity.this, "downloading", "please wait");
}
#Override
protected String doInBackground(Void... voids) {
if (!running) {
return null;
}
String result = null;
try{
URL url = new URL("http://192...");
HttpURLConnection urlConnection = (HttpURLConnection)
url.openConnection();
InputStream in = new BufferedInputStream (urlConnection.getInputStream());
result = inputStreamToString(in);
}catch(Exception e){
e.printStackTrace();
}
return result;
}
#Override
protected void onCancelled() {
boolean running = false;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
progressDialog.dismiss();
try {
..
} catch (JSONException e) {
textView.append("json is invalid");
e.printStackTrace();
}
}
}

Related

how can I write the code inside Application class to get Toast message every 5 seconds from the background

I am new to android and I want to get a Toast message from the background every 5 seconds but my app becomes not responding. I spent all the day to solve this problem :( but I can't
Can anyone help me?
thanks,
here is my code:
public void onCreate() {
super.onCreate();
System.out.println("Application Created");
new Thread(new Runnable() {
#Override
public void run() {
service1();
while (true) {
try {
Thread.sleep(5000);
mHandler.post(new Runnable() {
#Override
public void run() {
// here to update the UI
}
});
} catch (Exception e) {
// TODO: handle exception
}
}
}
}).start();
}
private void service1() {
Toast.makeText(appApplication.this, "Service 1", Toast.LENGTH_LONG).show();
}
You need to use runOnUiThread() when you want to update your UI from a Non-UI Thread, something like this:
private void showMessage() {
new Thread() {
public void run() {
while (true) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Service 1", Toast.LENGTH_LONG).show();
}
});
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
Or you can use Timer with TimerTask and Handler:
Timer timer;
TimerTask timerTask;
//we are going to use a handler to be able to run in our TimerTask
final Handler handler = new Handler();
// Call this to start showing the message.
private void startTimer() {
//set a new Timer
timer = new Timer();
//initialize the TimerTask's job
timerTask = new TimerTask() {
public void run() {
//use a handler to run process
handler.post(new Runnable() {
public void run() {
/**************************/
/** Do your process here **/
/**************************/
Toast.makeText(getApplicationContext(), "Service 1", Toast.LENGTH_LONG).show();
}
});
}
};
//schedule the timer, start run TimerTask then run every 5000ms i.e 5 seconds.
timer.schedule(timerTask, 0, 5000);
}
// Call this to stop the timer.
private void stopTimerTask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}

Create thread to run long-work but not responses

thread = new Thread(new Runnable() {
#Override
public void run() {
synchronized (datahandler) {
while (true) {
try {
if (datahandler.getCount() > 0) {
commitData();
}
datahandler.wait();
} catch (InterruptedException e) {
e.printStackTrace();
Log.e("Service", e.toString());
}
}
}
}
});
thread.start();
Commitdata to connect and commit data form datahandler to server. But I dont kow why it shows not respone dialog. If I do not close it, it continouns to commit. Why UI is influenced when I commit data in other thread
public class ThreadsLifecycleActivity extends Activity {
// Static so that the thread access the latest attribute
private static ProgressDialog dialog;
private static Bitmap downloadBitmap;
private static Handler handler;
private ImageView imageView;
private Thread downloadThread;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// create a handler to update the UI
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
imageView.setImageBitmap(downloadBitmap);
dialog.dismiss();
}
};
// get the latest imageView after restart of the application
imageView = (ImageView) findViewById(R.id.imageView1);
Context context = imageView.getContext();
System.out.println(context);
// Did we already download the image?
if (downloadBitmap != null) {
imageView.setImageBitmap(downloadBitmap);
}
// check if the thread is already running
downloadThread = (Thread) getLastNonConfigurationInstance();
if (downloadThread != null && downloadThread.isAlive()) {
dialog = ProgressDialog.show(this, "Download", "downloading");
}
}
public void downloadPicture(View view) {
dialog = ProgressDialog.show(this, "Download", "downloading");
downloadThread = new MyThread();
downloadThread.start();
}
// save the thread
#Override
public Object onRetainNonConfigurationInstance() {
return downloadThread;
}
// dismiss dialog if activity is destroyed
#Override
protected void onDestroy() {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
dialog = null;
}
super.onDestroy();
}
static public class MyThread extends Thread {
#Override
public void run() {
try {
// Simulate a slow network
try {
new Thread().sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
downloadBitmap = downloadBitmap("http://www.devoxx.com/download/attachments/4751369/DV11");
// Updates the user interface
handler.sendEmptyMessage(0);
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}
}
//==========================
You can sea in code that handlers are used to post message on GUI thread. further you can read about it over here
http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html
Also Read This http://android-developers.blogspot.de/2010/07/multithreading-for-performance.html

send heartbeat gcm?

I develop android app use GCM, i want to send heartbeat for every 5 minutes at once, i create it when service is run,these are my codes,
public class sendHeartbeat extends Service{
private Handler customHandler = new Handler();
private static final String TAG = "MyService";
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
Log.d(TAG, "onCreate");
}
#Override
public void onStart(Intent intent, int startId) {
Log.d(TAG, "onStart");
customHandler.postDelayed(updateTimerThread, 0);
}
#Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
}
private Runnable updateTimerThread = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
new syncGetHeartbeat().execute();
Log.d("send hearbeat","send hearrrrrrrbeat");
customHandler.postDelayed(this, 260000);
}
};
class syncGetHeartbeat extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... unsued) {
try {
String varId="naengoland";
String url = "http://mydomain.com/gcmserver/getHeartbeat.php?id="+varId;
getRequestJSON(url);
return null;
} catch (Exception e) {
Log.e(e.getClass().getName(), "service get hertbeat "+ e.toString());
return null;
}
}
#Override
protected void onProgressUpdate(Void... unsued) {
}
#Override
protected void onPostExecute(String sResponse) {
}
}
public String getRequestJSON(String Url){
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(Url);
try{
client.execute(request);
}catch(Exception ex){
}
return null;
}
}
I successfully send the heartbeat for every 5 minutes, but the problem is my app running slowly and consume battery a lot, is there any way to send heartbeat beside doing my way?
i mean,the better method than my method.
Please help.
Using TimerTask provides better performance than using Thread (ref).. However TimerTask isn't good in handling multiple threads at the same time which isn't a concern in your case because you are doing one task repeatedly.
here is the code for Timer:
first initialize a Timer:
private Timer timer;
in onCreate:
timer = new Timer();
then within onStart:
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
new syncGetHeartbeat().execute();
Log.d("send hearbeat","send hearrrrrrrbeat");
}
}, 0, 300000); //means start at 0 second and each 5 mins (300000 ms) run the task
I'm not sure if there is another solution that has better performance however this is absolutely better than running thread in a fixed rate.

Getting error while implementing thread android

Am new in android .. am trying to implement thread in a android. But am getting error .. I googled and getting answer "AsyncTask", but truly i dont know how to implement
Error message
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
my code
final Thread thread = new Thread(){
#Override
public void run() {
try {
DatabaseHandler dbh = new DatabaseHandler(test.this);
result=dbh.Verify(1);
if(result != ""){
getData();
progress.dismiss();
}
else{
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
Use following code to run in UI thread.
Runnable runnable = new Runnable() {
#Override
public void run() {
handler.post(new Runnable() { // This thread runs in the UI
#Override
public void run() {
DatabaseHandler dbh = new DatabaseHandler(test.this);
result=dbh.Verify(1);
if(result != ""){
getData();
progress.dismiss();
}
else{
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
};
new Thread(runnable).start();
Seems like you need to create your handler in MainActivity and then pass it further. Like so:
private Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler();
}

Android Task AsyncTask issue with postExec

the Problem I am having is that the PostExecute is not firing.
I see the log tag for background but P.E. never fires.
I am invoking this task from a timer like this:
findViewById(R.id.buttonstart).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
openFile("FeedTimerTask.html");
Timer t = new Timer("FeedTimerTask", true);
timerTask = new FeedTimerTask();
t.schedule(timerTask, 2000, 20000);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Runnable runme = new Runnable() {
#Override
public void run() {
timestart = Calendar.getInstance().getTimeInMillis();
provider.refreshNoCache();
}
};
class FeedTimerTask extends TimerTask{
#Override
public void run() {
try{Looper.prepare();}catch(Exception e){};
runme.run();
}
}
Here is the main task itself from inside the dataprovider class invoked with "provider.refreshNoCache();" above:
// threaded rteftesh tasks
#SuppressWarnings("rawtypes")
public class RefreshTask extends SupportAsyncTask {
private int errorcodecode = 0;
private ProgressDialog dialog=null;
private Exception mainExeption=null;
protected String waitMessage = "Laddar ner information..";
private boolean useCache;
public RefreshTask(boolean useCache) {
this.useCache = useCache;
}
public void onPreExecute() {
data = null;
if (showSpinnerOnRefresh){
dialog = ProgressDialog.show(context, "", waitMessage , true);
dialog.show();
}
}
protected Object doInBackground(Object... params) {
errorcodecode = 1;
try {
invokeFeedRead();
Log.e("DataProvider", "Bkgtask...");
errorcodecode = 0;
} catch (BrJSONException e) {
Log.e("[ERROR]","PROVIDER "+e.getMessage());
mainExeption = e;
errorcodecode = 1;
} catch (IOException e) {
Log.e("[ERROR]","PROVIDER "+e.getMessage());
mainExeption = e;
errorcodecode = 2;
} catch (Exception e) {
Log.e("[ERROR]","PROVIDER "+e.getMessage());
mainExeption = e;
errorcodecode = 3;
}
if (errorcodecode==0){
}
return null;
}
#Override
protected void onCancelled() {
super.onCancelled();
Log.e("DataProvider", "Cancelled...");
if (dialog != null)
try{dialog.dismiss();}catch(Exception e){}
BrAlert.Show(context, "Obs", BrAppConfig.ServerError+" (timeout)", 0);
onError_IO(new IOException("Timeout!"));
errorcodecode=2;
}
#Override
protected void onPostExecute(Object result) {
// super.onPostExecute(result);
Log.e("DataProvider", "PostExec...");
if (dialog != null)
try{dialog.dismiss();}catch(Exception e){}
switch (errorcodecode) {
case 0:
onFeedLoaded();
cacheAge = System.currentTimeMillis();
break;
case 1:
onError_DataFormat(mainExeption);
break;
case 2:
onError_IO(mainExeption);
break;
default:
onError_GeneralExeption(mainExeption);
}
}
}
Your task is cancelled even before it reached onPostExecte method. If the task is cancelled before it reaches onPostExecute Method. It will not trigger onPostExecute but trigger onCancelled Method. Please provide enough time to finish the task.
I found out the problem in the end. It was to do with the scope.
I needed a handler to invoke the other thread.
Here is the solution for others may find helpful:
in on create:
tickHandler = new Handler();
tickTimer = new Timer();
tickTimer.schedule(new FeedTimerTask(),
0,
50000); //FPS
The handler class.
class FeedTimerTask extends TimerTask{
private Runnable runable;
public FeedTimerTask(){
super();
runable = new Runnable(){
#Override
public void run() {
timestart = Calendar.getInstance().getTimeInMillis();
provider.refreshNoCache();
}
};
}
#Override
public void run() {
tickHandler.post(runable);
}
}

Categories

Resources