I'm using Loaders in my android App to retrieve data from the web. in my onCreate() method I initialize the loader. Once the data is retrieved, I can access them in onLoadFinished() method. This is working fine.
I'm trying to add a time-out so that if the request takes more than 15 seconds, I destroy the loader and re-initiate it. I'm using the following to achieve this:
private void timeOutTimer()
{
final Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
myHandler.post(recreateLoader);
t.cancel();
}
}, 15000);
}
final Runnable recreateLoader = new Runnable() {
public void run() {
if(getLoaderManager().getLoader(MY_LOADER) != null || getLoaderManager().getLoader(MY_LOADER) != null)
{
Toast.makeText(getApplicationContext(),"Reconnecting..",Toast.LENGTH_SHORT).show();
getLoaderManager().destroyLoader(MY_LOADER);
ReInitiateLoader();
}
}
}
};
The problem is that onLoadFinished is never called. It seems that initiating the Loader in a thread doesn't work. Is there a solution for this?
Related
I have been using handler inside service class, the handler is responsible for sending location every 5 seconds via socket. When logging out, the service gets stopped but the handler still running.
I tried every possible way, By using any boolean variable is not feasible in my case because i have to start again that handler.
public Runnable mn_Runnable12 = new Runnable() {
public void run() {
gps = new GPSTracker(LocationService.this);
if (gps.canGetLocation()) {
latString = Double.toString(gps.getLatitude()); // Live
logString = Double.toString(gps.getLongitude());
connection= MyApplication.getInstance().getConnection();
if (connection!=null&&connection.isConnected()) {
sendLocation();
}
}
}
};
this is inside onCreate() of service.
T.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
mHandler12.postDelayed(mn_Runnable12, 5000);
}
},
5000,
5000);
I try to stop the handler in onDestroy method of service, service gets topped but the handler still running.
#Override
public void onDestroy() {
System.out.println("Location Service Detaroy-----");
if (connection.isConnected()) {
unSubscribe();
}
mHandler12.removeCallbacksAndMessages(null);
mHandler10.removeCallbacksAndMessages(null);
}
You Also have to cancel Timer Since its running repeatedly with an interval.
First cancel timer and then remove handlers callback.
T.cancel();
T.purge();
// remove handler here
I created one handler to repeat a task repeatedly and I also want to destroy it within that handler once a condition has been met.
pinHandler = new Handler();
Now I created two functions separately to start and stop the task.
void startRepeatingPins() {
mPinSetter.run();
}
Runnable mPinSetter = new Runnable() {
#Override
public void run() {
try{
System.out.println("PinIndwx count is :"+pinIndexCount);
if(pinIndexCount==(plist.size()-1))
{
stopUpdatingPins();
pinIndexCount=0;
//pinHandler.removeCallbacks(mPinSetter);
System.out.println("Handler stopped by itself.");
}
else
{
updatePoint(plist.get(pinIndexCount));
pinIndexCount++;
}
}
finally {
pinHandler.postDelayed(mPinSetter, pinInterval);
}
}
};
private void stopUpdatingPins()
{
pinIndexCount=0;
pinHandler.removeCallbacks(mPinSetter);
System.out.println("Called the stop function.");
}
Now, the issue is that, if I call the stopUpdatingPins function , the handler stops but when I try to stop it automatically from within the handler, it just doesn't stop. Although the stopUpdatingPins function does get called.
Change You startRepeatingPins() like this, You should not directly call the run. If your run like this then there is no point of removing this from Handler. So attach Runnable with Handler.
void startRepeatingPins() {
pinHandler.post(mPinSetter);
}
You added post delay in finally that means you are stopping at first if loop and starting again in finally, So it's never stopping. So Change your runnable like this,
Runnable mPinSetter = new Runnable() {
#Override
public void run() {
System.out.println("PinIndwx count is :"+pinIndexCount);
if(pinIndexCount==(plist.size()-1))
{
stopUpdatingPins();
pinIndexCount=0;
//pinHandler.removeCallbacks(mPinSetter);
System.out.println("Handler stopped by itself.");
}
else
{
updatePoint(plist.get(pinIndexCount));
pinIndexCount++;
pinHandler.postDelayed(mPinSetter, pinInterval);
}
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
loadImageFromUrl(url);
}
}, 2000);
addTouchlistener();
addButtonListener();
}
private void loadImageFromUrl(String url) {
Picasso.with(iv.getContext())
.load(url)
.networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
.into(iv);
}
the "url" is my http server, i will be receiving the .jpg continuously.
i want repeat the function every 2s to receive the .jpg
In this case, the first time load the image will be delay 2s
but, when i update my photo, it can not show the new photo
i also tried the timer "scheduleAtFixedRate" to repeat but it's not work.
Because a Handler only runs what you post to it once. It doesn't do so repeatedly. To do so repeatedly, the runnable needs to repost itself at the end.
Although I suggest you don't do it this way. How often do you really change the image? Every few minutes? Few hours? Checking every 2 seconds is ridiculous, you're wasting bandwidth 99% of the time. Use a much longer timer. Better yet, use push messaging to tell the client when to reload.
This is a working example I have in a Fragment, but the logic is the same for an Activity.
I included extra code to turn off the downloads when the app goes onPause().
protected Handler programacionTimer;
protected Runnable programacionRunnable;
....
#Override
public void onResume() {
super.onResume();
if (programacionTimer == null) {
programacionTimer = new Handler();
}
if (programacionRunnable == null) {
programacionRunnable = new Runnable() {
#Override
public void run() {
//Here what you to do (download the image)
programacionTimer.postDelayed(this, 2000);
}
};
}
programacionTimer.postDelayed(programacionRunnable, 2000);
}
#Override
public void onPause() {
super.onPause();
programacionTimer.removeCallbacks(programacionRunnable);
programacionRunnable = null;
}
I would like to periodically check for updates doing network call every 30 sec and update listview accordingly, only if my screen is in foreground (thus not from service). What I am doing for that is -
private void refreshPeriodically()
{
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 {
new callToMyAsyncTask().execute(context);
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 30*1000); //execute in every 30 sec
}
but, that hangs my list while scrolling.
What should I do for that?
You shouldn't use handler. When you call handler.post() it will run on UI thread so your list will freeze. Start a new callToMyAsyncTask in run method in TimerTask without using handler and you can call timer.cancel() when your activity is not in foreground.
Also I think you should use scheduleAtFixedRate instead of schedule.
However I think you may have some problems without service. When you cancel timer it will not cancel current callToMyAsyncTask and when it call onPostExecute activity is no longer available. But I don't know it will crash or not.
In an android project of mine I'm using the jamod library for Modbus communication and it works alright. Except when the network connection isn't available then my asynchronous task will be stuck on transaction.execute for seconds. I would like to cancel it after a given timeout. I tried to implement a handler for this to cancel the asynchronous task:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (task.getStatus() == AsyncTask.Status.RUNNING
|| task.getStatus() == AsyncTask.Status.PENDING) {
task.cancel(true);
}
}
}, WRITE_TASK_TIMOUT);
But this approach won't work. I looked into the library and saw that the ModbusTCPTransaction.execute() method uses synchronized().
Does this mean i have no chance to cancel this method after x seconds?
You could try to use Android class Future. It has method to set the timeout period of the thread execution.
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Task());
future.get(5, TimeUnit.SECONDS);
static class Task implements Callable<String> {
#Override
public String call() throws Exception {
//ModbusTCPTransaction.execute()
return null;
}
}