After executing this line:
WifiManager man = ((WifiManager) ctx.getSystemService(Context.WIFI_SERVICE));
A thread labeled "WifiManager" will show up. In the Java source file for WifiService.java line 203:
HandlerThread wifiThread = new HandlerThread("WifiService");
wifiThread.start();
mWifiHandler = new WifiHandler(wifiThread.getLooper());
Problem is, every time our app is closed and reopened it creates a new thread, run it 5 times and you have 5 threads. Not sure if there is anyway to stop it?
EDIT
Changed to getApplicationContext to make sure the context it was accessing was consistent and all was well. I still get a thread labeled "WifiService," but I only get one thread over multiple runs.
I believe you are creating a new WifiManager in your started/stopped (Context) Activity.
A note from Context.getSystemService()
Note: System services obtained via this API may be closely associated with the Context in which they are obtained from. ...
Also from ContextImpl.java:1478 and :227
#Override
public Object getSystemService(String name) {
ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
return fetcher == null ? null : fetcher.getService(this);
}
...
service = cache.get(mContextCacheIndex);
if (service != null) {
return service;
}
...
It uses a map to cache system services, so I believe if you use the same context like Application, you wouldn't run into this problem. I am not sure if this is the right way of solving this problem however, if having threads laying around a bigger issue for you, it may worth while.
When you get the instance of a system service using Context.getSystemService(), you are not calling the constructor of the service. Instead, you are actually getting an instance of the service using IBinder so as to do a remote procedure call on it. So the constructor of WiFiService.java will not be called every time you get an instance of it. Where exactly are you seeing this thread pop up?
I hope your application is the only application which is accessing WifiManager. Please check at the same time with some dummy application which access WifiManager; in that case it should not create a new thread.
Related
I have the following scenario. My application reads from a configuration file in which I have defined queues, its exclusiveness, thread count and some other details. When application is started, it reads from that configuration and creates DirectMessageListenerContainer for each stated entry. I save these containers in a map in which I associate each of them with a custom name I have given.
On startup, if any failure happens, application fails to run which is what I want.
Now, about the problem. I created a reload method which allows users to change configuration without restarting the application through JMX. So, when the configuration file is changed, and if reload method is called, the following process is performed. The validity of new configuration is checked, if it is correct, it is used to set up the new one. To do so, I first, stop all the containers, then destroy them. After that, I initialize new containers. That's it. The issue is that, what happens when an exception occurs on stopping, destroying or any other next step. I handle the exception, but the issue is that it will leave the current setting broken or half-baked. I would like to have a rollback feature, but I am not sure how that can be done. Because after checking the validity of new configuration, I set it as the current one.
I can save the current setting, check if the new one works, if not then I can initialize the previous one, again. However, I can run into another exception when initializing the previous one.
Here's the reload function. RabbitManager is the class I have created, it has nothing special, just does actions like stop, destroy, etc.
public String reloadConfiguration() {
Rules newRules;
// checking validity of new rules, setting it, handling exceptions...
try {
// setting new rules
// rules variable saves the current rules
rules = newRules;
// basically calls stop in all the containers
rabbitManager.stopAll();
// basically calls destroy in all the containers
rabbitManager.destroyAllContainers();
rabbitManager
.init(rules) // initializes an empty map and sets rules as new rule.
.registerListeners(); // reads rules and creates DirectMessageListenerContainer for each setting
log.info("Configuration has been successfully changed, and stopped");
// returns are for jConsole/monitoring
return "Configuration has been successfully changed, and stopped";
} catch (Exception ex) {
log.error("Exception occurred - "+ex.getMessage(), ex);
// returns are for jConsole/monitoring
return "Exception : "+ex.getMessage();
}
}
I hope my question is clear, if anything is needed or you think the current approach has issues, or maybe I am missing some point, please let me know. Sorry for the vague title, though.
Why don't you just stop() the containers and only destroy them when the new ones are good. If the new config fails, just start() the old containers after destroying the new ones.
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.
How does async JMS work? I've below sample code:
public class JmsAdapter implements MessageListener, ExceptionListener
{
private ConnectionFactory connFactory = null;
private Connection conn = null;
private Session session = null;
public void receiveMessages()
{
try
{
this.session = this.conn.createSession(true, Session.SESSION_TRANSACTED);
this.conn.setExceptionListener(this);
Destination destination = this.session.createQueue("SOME_QUEUE_NAME");
this.consumer = this.session.createConsumer(destination);
this.consumer.setMessageListener(this);
this.conn.start();
}
catch (JMSException e)
{
//Handle JMS Exceptions Here
}
}
#Override
public void onMessage(Message message)
{
try
{
//Do Message Processing Here
//Message sucessfully processed... Go ahead and commit the transaction.
this.session.commit();
}
catch(SomeApplicationException e)
{
//Message processing failed.
//Do whatever you need to do here for the exception.
//NOTE: You may need to check the redelivery count of this message first
//and just commit it after it fails a predefined number of times (Make sure you
//store it somewhere if you don't want to lose it). This way you're process isn't
//handling the same failed message over and over again.
this.session.rollback()
}
}
}
But I'm new to Java & JMS. I'll probably consume messages in onMessage method. But I don't know how does it work exactly.
Do I need to add main method in JmsAdapter class? After adding main method, do I need to create a jar & then run the jar as "java -jar abc.jar"?
Any help is much appreciated.
UPDATE: What I want to know is that if I add main method, should I simply call receiveMessages() in main? And then after running, will the listener keep on running? And if there are messages, will it retrieve automatically in onMessage method?
Also, if the listener is continuously listening, doesn't it take CPU??? In case of threads, when we create a thread & put it in sleep, the CPU utilization is zero, how doe it work in case of listener?
Note: I've only Tomcat server & I'll not be using any jms server. I'm not sure if listener needs any specific jms server such as JBoss? But in any case, please assume that I'll not be having anything except tomcat.
Thanks!
You need to learn to walk before you start trying to run.
Read / do a tutorial on Java programming. This should explain (among other things) how to compile and run a Java program from the command line.
Read / do a tutorial on JMS.
Read the Oracle material on how to create an executable JAR file.
Figure out what it is you are trying to do ... and design your application.
Looking at what you've shown and told us:
You could add a main method to that class, but to make an executable JAR file, you've got to create your JAR file with a manifest entry that specifies the name of the class with the main method.
There's a lot more that you have to do before that code will work:
add code to (at least) log the exceptions that you are catching
add code to process the messages
add code to initialize the connection factory and connection objects
And like I said above, you probably need some kind of design ... so that you don't end up with everything in a "kitchen sink" class.
if I add main method, should I simply call receiveMessages() in main?
That is one approach. But like I said, you really need to design your application.
And then after running, will the listener keep on running?
It is not entirely clear. It should keep running as long as the main thread is alive, but it is not immediately obvious what happens when your main method returns. (It depends on whether the JMS threads are created as daemon threads, and that's not specified.)
And if there are messages, will it retrieve automatically in onMessage method?
It would appear that each message is retrieved (read from the socket) before your onMessage method is called.
Also, if the listener is continuously listening, doesn't it take CPU???
Not if it is implemented properly.
In case of threads, when we create a thread & put it in sleep, the CPU utilization is zero, how doe it work in case of listener?
At a certain level, a listener thread will make a system call that waits for data to arrive on a network socket. I don't know how it is exactly implemented, but this could be as simple as an read() call on the network socket's InoutStream. No CPU is used by a thread while it waits in a blocking system call.
This link looks like a pretty good place with examples using Oracle AQ. There's an examples section that tells you how to setup the examples and run them. Hopefully this can help.
Link to Oracle Advanced Queueing
My problem is this:Google App Engine allows cron jobs to be active for only 30 seconds before an DeadlineExceededException is thrown. And my app that isn't suited for the google app engine platform from this point of view, needs to call a time-consuming cron job.
One solution that I figured out was to calling another Servlet (Servlet2) and let that Servlet2 do the job for me, Servlet_2 would be a regular Java Servlet.To achieve that, I was thinking of creating a session from my cron job Servlet_1, call the other Servlet_2, test the session and then let the server do the jobs required and in the end invalidate the session.
The call from Servlet_1 should not be redirecting to Servlet_2, because that will put me back in square one again.
Now to my question: Do you think this will work? And if yes and an DeadlineExceededException acure, would the Servlet_2 stop from working as well, even if I put all the code in the destroy method of the Servlet_2?
my code:
//Servlet_1
try {
HttpSession session = request.getSession(true);
session.setAttribute("referingPage", "server is calling");
request.getRequestDispatcher("/Servlet_2.do").forward(request, response);
}catch(DeadlineExceededException e) {
e.printStackTrace();
}
//Servlet_2
#Override
public void destroy() {
HttpSession session = request.getSession(true);
String value = (String)session.getAttribute("referringPage");
if(value.equals("server is calling")) {
// Do the time demanding stuff
}
session.invalidate();
}
Would be grateful for an answer!
You only have 30 seconds to produce finish execution and there's no way around that. Doing a forward doesn't spawn a new thread or anything, it's still executing within the 30 second time limit.
I'd try to figure out some way to serialize what you're doing, or pause it and stick your state in memcache. When you start processing again, check memcache to see if you need to pick up form where you left off.
Google App Engine is working on long running background processes, and I hope then come out with a solution soon. I'm in the same boat.
Mark
Why not use a task queue. You put a task on the queue - it works for 29 seconds and then stops but, before it stops, it puts another task on the queue. As long as the payload has a marker to indicate where to restart then you have a chained set of tasks that can run for as long as you want to consume (and pay for) CPU.
Edit
This question has gone through a few iterations by now, so feel free to look through the revisions to see some background information on the history and things tried.
I'm using a CompletionService together with an ExecutorService and a Callable, to concurrently call the a number of functions on a few different webservices through CXF generated code.. These services all contribute different information towards a single set of information I'm using for my project. The services however can fail to respond for a prolonged period of time without throwing an exception, prolonging the wait for the combined set of information.
To counter this I'm running all the service calls concurrently, and after a few minutes would like to terminate any of the calls that have not yet finished, and preferably log which ones weren't done yet either from within the callable or by throwing an detailed Exception.
Here's some highly simplified code to illustrate what I'm doing already:
private Callable<List<Feature>> getXXXFeatures(final WiwsPortType port,
final String accessionCode) {
return new Callable<List<Feature>>() {
#Override
public List<Feature> call() throws Exception {
List<Feature> features = new ArrayList<Feature>();
//getXXXFeatures are methods of the WS Proxy
//that can take anywhere from second to never to return
for (RawFeature raw : port.getXXXFeatures(accessionCode)) {
Feature ft = convertFeature(raw);
features.add(ft);
}
if (Thread.currentThread().isInterrupted())
log.error("XXX was interrupted");
return features;
}
};
}
And the code that concurrently starts the WS calls:
WiwsPortType port = new Wiws().getWiws();
List<Future<List<Feature>>> ftList = new ArrayList<Future<List<Feature>>>();
//Counting wrapper around CompletionService,
//so I could implement ccs.hasRemaining()
CountingCompletionService<List<Feature>> ccs =
new CountingCompletionService<List<Feature>>(threadpool);
ftList.add(ccs.submit(getXXXFeatures(port, accessionCode)));
ftList.add(ccs.submit(getYYYFeatures(port accessionCode)));
ftList.add(ccs.submit(getZZZFeatures(port, accessionCode)));
List<Feature> allFeatures = new ArrayList<Feature>();
while (ccs.hasRemaining()) {
//Low for testing, eventually a little more lenient
Future<List<Feature>> polled = ccs.poll(5, TimeUnit.SECONDS);
if (polled != null)
allFeatures.addAll(polled.get());
else {
//Still jobs remaining, but unresponsive: Cancel them all
int jobsCanceled = 0;
for (Future<List<Feature>> job : ftList)
if (job.cancel(true))
jobsCanceled++;
log.error("Canceled {} feature jobs because they took too long",
jobsCanceled);
break;
}
}
The problem I'm having with this code is that the Callables aren't actually canceled when waiting for port.getXXXFeatures(...) to return, but somehow keep running. As you can see from the if (Thread.currentThread().isInterrupted()) log.error("XXX was interrupted"); statements the interrupted flag is set after port.getFeatures returns, this is only available after the Webservice call completes normally, instead of it having been interrupted when I called Cancel.
Can anyone tell me what I am doing wrong and how I can stop the running CXF Webservice call after a given time period, and register this information in my application?
Best regards, Tim
Edit 3 New answer.
I see these options:
Post your problem on the Apache CXF as feature request
Fix ACXF yourself and expose some features.
Look for options for asynchronous WS call support within the Apache CXF
Consider switching to a different WS provider (JAX-WS?)
Do your WS call yourself using RESTful API if the service supports it (e.g. plain HTTP request with parameters)
For über experts only: use true threads/thread group and kill the threads with unorthodox methods.
The CXF docs have some instructions for setting the read timeout on the HTTPURLConnection:
http://cwiki.apache.org/CXF20DOC/client-http-transport-including-ssl-support.html
That would probably meet your needs. If the server doesn't respond in time, an exception is raised and the callable would get the exception. (except there is a bug where is MAY hang instead. I cannot remember if that was fixed for 2.2.2 or if it's just in the SNAPSHOTS right now.)