More and more Threads are causing my app to lag - java

In my app I got some activities and a ReceiverThread.class.
The Thread is started from two different activities. And everytime I switch to another Activity and recall the former active Activity it starts a new Thread. So if I do some test on my app for about 10 Minutes or the app is simply used for some time, there is a mass of Threads open and all do the same.
Most of the time the Threads are on TimedWait.
This gives me wrong data and causes the app to lag hard, sometimes its not even responding.
Is there a good possibility to stop a thread onPause() or onStop() ? Because many of the methods are deprecated. Or how to resume a previous started Thread and so prevent the Activity from creating a new one?
This is my ReceiverThread.run():
public void run() {
initiateCAN();
while (true) {
try {
Thread.sleep(60);
mHandler.post(r);
} catch (InterruptedException e) {
break;
}
}
}
If something is not clear or missing, please feel free to ask and I will edit my post, but don't just simply downvote.

The recommended way to do this is to use the built-in interrupt system. You can then stop the thread by calling Thread.interrupt() (best in onPause() if you don't want multiple instances). Your run method would need to be somewhat changed:
public void run() {
initiateCAN();
try {
while (!isInterrupted()) {
Thread.sleep(60);
mHandler.post(r);
}
} catch (InterruptedException e) {
}
}
While this might work, it's still better to use a Service or another way to make sure there is only one instance at one time (maybe fragments instead of activities?).

You can use Android Services, and that service starts the thread. When you switch the activity, the services is running and not is necessary start a new thread.

Related

Proper use of threads in using Java and Servlets

I am pretty new in the whole Servlets area and I am trying to implement a method that will wait for an a time variable given by a user( e.g 1 minute) and then it will start a countdown until the given time reaches 0. I thought the only way I can do that is by using Threads.
I am exporting my Java Project as a war , deploy it but when I import 1 minute the webpage does not prints anything until I reload it and If I go back using my browser the thread is still running.
The code below executes the thread.
Can you please suggest me whether I should use the asychronous threads (and maybe explain a little bit the difference with normal threads) or I can continue using the Thread as it is.
if(minutes<=0) {
out.println("<center><h3>Time cannot be negative</h3></center>");
}
else
{
new Thread(new Runnable(){
public void run() {
try {
out.println("<center><h3>Minutes :"+(minutes)+"</h3></center>");
Thread.sleep(minutes*60000);
out.println("<p align=\"CENTER\"> Return<br>");
} catch (InterruptedException e) {
out.println("Interruption Found");
}
}
}).start();
}
}
You have to answer the HTTP request, without delay. A thread isn't a solution for that.
You may use one of the following:
Using some Ajax (client side controlled)
WebSocket (server side controlled)

Checking if a Thread is sleeping always returns true

I currently have the following problem:
I have made a 'Cache Updater Thread', which checks for updates and then sleeps for some amount of time. I have also build a Button, which enables the user to check for updates manually. The Thread is built like this:
public static Thread cacheUpdater = new Thread(new Runnable() {
int milliSecondSleepTime = 10000;
public void run() {
try {
cacheUpdater.setPriority(Thread.MIN_PRIORITY);
//Infinite loop
while (!terminate) {
syncStatus.set(0);
//Check for updates with some methods, not important here.
syncStatus.set(1);
Thread.sleep(this.milliSecondSleepTime);
}
}
catch (InterruptedException e) {
//First check if it is termination time
if (!terminate) {
syncStatus.set(0);
this.run();
}
}
catch (Exception e) {
System.out.println(e);
}
return;
}
});
If the user clicks the manual-update button, the following code is being runned:
#FXML public void syncOnRequest() {
//Only call interrupt, because then it will start again when terminate is still false
CacheManager.cacheUpdater.interrupt();
System.out.println(CacheManager.cacheUpdater.getState().equals(State.TIMED_WAITING));
while (!CacheManager.cacheUpdater.getState().equals(State.TIMED_WAITING)) {
//LOOP FOREVER
}
//Some code that needs to be executed after the cache is updated
}
I would like to continue executing code in the syncOnRequest() method, when the cache updater is ready with its manual update. I had the idea to check if it is sleeping, but this is not working, because the System.out.println() immediately returns true. I have measured the time it takes to do the update, and its between 200 and 400 ms.
What am I doing wrong here? And why is it always returning true?
Additional question: sometimes a click on the button just kills the Thread, because it just woke up. The InterruptedException is not thrown.
How can I make sure the Thread will also restart in that case?
Note that Thread#interrupt() is the only polite way to ask your thread to interrupt itself (unless you explicitly implement another). Using it to restart the check is therefore a bad practice. So is checking the thread state for synchronization purposes and exposing the thread that keeps your cache up-to-date to external clients.
You manager should have a updateCache() method you will call directly from UI code and auto-update thread will call the same method periodically*. In that method, make sure that access to your cached data is either correctly synchronized or it happens atomically.
*) Instead of implementing your own periodic thread, consider using
Timer and TimerTask classes as well as making it a daemon thread.

How Do I periodically Check For Updates on a Parse Server? [duplicate]

This question already has an answer here:
How to call asyncTasks periodically
(1 answer)
Closed 8 years ago.
Helly Community. I´m fairly new to Android and probably the biggest noob when it comes to networking and backend.
Right now I´m having following problem.
I´m building a simple chatting application and want my app to check the Parse server for a specific message parseobject.
Getting the Objects, working with them and deleting them works fine.
If i do it only once.
This is how I get messages from the Cloud and add them to my App Layout.
ParseQuery<ParseObject> query = ParseQuery.getQuery("message");
query.whereEqualTo("recipient", getRemote_id());
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> messages, ParseException e) {
if(messages != null){
Iterator itr = messages.iterator();
while(itr.hasNext()){
ParseObject message = (ParseObject)itr.next();
addMessageToLayout(message.getString("text"), "in", "new", "");
try {
message.delete();
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
});
I want my app to check for new messages the whole time.
Ive tried with AsyncTask and a while(true) loop. The loop constantly creates new asynctask objects.
As result the app doesn´t react anymore and crashes.
When I use an instance of the runnable class im getting following error: NetworkOnMainThreadException, and the App crashes.
Because of this error i tried using asynctask in the first place. Isn´t a runnably object running on a different thread than the main thread as well?
I tried putting the thread to sleep for some seconds, still the app crashes in case of the async task.
Could the Problem be following: Im using anoher runnable object to update some animation in my app.
I also tried not using any kind of threading as the parse methods already work in background so they probably dont even need one. Again the app crashes because of an NetworkOnMainThreadException.
///_////
The weirdest thing comes now. If i´m not using a loop, and just check for messages when i enter the activity at first i´m getting an NetworkOnMainThreadException, but then the application somehow recovers into the newly opened activity and loads my messages from the server.
During that time of course the UI is blocked though. Still, thats the only way i can get it to work right now.
Doing it with a Handler and the TimerTask works, I can´t seem to close the thread when i exit the Activity though.
Here my code:
public void startLookingForMessages(){
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
new GetMessagesTask().execute();
}
});
}
};
timer.schedule(task, 0, 1000);
}
I found out that im getting the NetworkOnMainThreadException only if i´m trying to shut down the thread or close the while loop when calling onStop(). If I let the thread do its own thing, that means not putting in any code to stop it any time, my app works fine.
How could i overcome this problem?
I know this is getting kinda long. But maybe someone has the same Problem and can get some Info here.
Thanks you for your help already =)
Don't do it this way. Just don't.
Think about it: you're calling an AsyncTask to check periodically if something is there. Now, that gets to be quite expensive. Think about the battery and network resources you waste if that message is not there. Therefore, you waste a lot of resources. It's not a good idea to do it like this. You waste the user's resources. In addition, you also need a service to run in the background, as your app will not always be running.
A good way to solve this is to use Google Cloud Messaging. So what Google Cloud Messaging does is it "pings" a device every time there's an update. This makes life easier on you, as you only need to check if your app has received one of these pings, and it also saves battery and network resources.
If you're using PHP for your server-side application, you can use this to get started with GCM and PHP: GCM with PHP (Google Cloud Messaging)
This page on Google's website should also help with implementing it.
By using GCM, you'll also avoid having infinite loops or checking for more information every x minutes. You don't have to check yourself if new information is available; it'll ping you when it's available.

Android - Make app send heartbeat to server

I need to implement a regular heartbeat.
The heartbeat itself is a simple HTTP-GET call to my server.
The thing is I want to send it as long as my app is open. When I close the app the sending should stop.
I read a few things about Services and AlarmManager but how can I call/stop them when navigating through my app activities?
This also seems nice but still the same problem:
final Handler handler = new Handler();
Runnable runable = new Runnable() {
#Override
public void run() {
try{
//do your code here
//also call the same runnable
handler.postDelayed(this, 1000);
}
catch (Exception e) {
// TODO: handle exception
}
finally{
//also call the same runnable
handler.postDelayed(this, 1000);
}
}
};
handler.postDelayed(runable, 1000);
Could anybody maybe post a good example or a link?
Thanks!
The thing is I want to send it as long as my app is open. When I close
the app the sending should stop
In android a bit harder than in iOS, but lets do it:
In Android you don't have a callback at application level when the app it goes to background or is killed. Instead of thins you should handle at each Activity onStop Method for example. Take a look at Activity lifecycle:
or onDestroy method. Note:
When an activity it isn't visible anymore it can be because your app is gone to background, closed or other activity is visible. You have to decide which case is and use your HTTP Get / Post, or stop it , when needed.
Here is a sample code with Async task to send data over HTTP.
I implemented a simple timeout using a similar Handler to your code. When an Activity calls onPause trigger the timeout on a 10 second delay, when an Activity calls onResume cancel that call with removeRunnable(...) if the timeout code fires you know the user has left your app (this is the reason for the 10 second timeout, to give a new Activity time to launch if there is one).
You could add something in your timeout code to kill the heartbeat. e.g. cancel the heartbeat Runnable

Application continues to run after System.exit(0) is called - Java

I'm trying to clean up resources in my application before it shuts down, following on from my previous question (Detecting When A Java Application Closes) I have implemented the following code which performs the cleanup operation perfectly.
//Intercept when the application closes
Runtime.getRuntime().addShutdownHook(new Thread()
{
#Override
public void run()
{
//Reclaim resources from MIDI usage
if(_midiInstance.CleanUp())
{
Logger.Add("Closed resources successfully on ShutDown");
}
else
{
Logger.Add("Failed to close all resources on ShutDown");
}
System.exit(0);
}
});
Although the System.exit(0); call is understood and processed the application continues to run, just without a visiable GUI. I've thought about placing the System.exit(0) call just outside of the Thread but then it's out of scope, there aren't any other threads or streams running.
Is there an additional step I need to take when hooking in to the ShutDown event to ensure everything closes?
Thanks for your time, I greatly appreciate it.
After reading your other question, it seems like your are probably not calling dispose() on your window(s). If true, that would explain the cause of your problem.
You need to over ride the windows close button:
//overriding the windowClosing() method will allow the user to click the close button
addWindowListener(
new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
By doing this the program will close not just become invisible.

Categories

Resources