Basically I have a maps Activity that when started it starts up a thread that slowly loads in all of the map markers (overlays).
Sometimes (probably like 75% of the time) when you attempt to interact with the map while this thread is running, it throws a RuntimeException with message "sending message to a handler on a dead thread". I have concluded that this error is not thrown if you wait to interact with the map until after the thread is done.
So my initial questions are: does the maps API have known threading errors? Is there a specific way one needs to go about loading maps data asynchronously? Maybe there is some notify method I need to be calling?
Basically if I run the thread but comment this line:
mv.getOverlays().add(pin);
The thread runs like normal but does not add overlays, and the app does not crash.
I will show more code if we need it.
Thanks
You may want to look at using an AsyncTask. Here's some good background information on the subject: http://developer.android.com/resources/articles/painless-threading.html
Related
I am learning Android app development from Udacity.com by Google engineers and they said,
"It is not a good idea to use 'AsyncTask' as it is not attached to an activity life cycle. The virtual machine will hold on to the activity object as long as the Asynctask is running, even after Android has called onDestroy( ) method for the activity and expect it to be discarded.
If you rotate your phone, the behavior is to destroy the current activity and instantiate a new one. The naive AsyncTask implementation now has two threads trying to do the same update. So it is not the best pattern for a potentially very long running background operation , such as fetching from web services. If you leave the app, the asyncTask will run as long as as the process is kept alive , but will run at a lower priority, and your process will be the first thing to be killed if the device needs more resources. "
1) If using AsyncTask is disadvantageous why was it created? What would have been the design philosophy or the cause to create it in spite of having services(or something similar to achieve same kind of functionality)?
2) What are the situations where Asynctask should be used for betterment compared to Services/similar options available in Android?
3) What are the situations/places Asynctask should never be used?
Please do not downvote this question. I searched Stackoverflow and I couldn't find a similar question.
Advantages of AsyncTask
Provides generic solution for all network calls
Publish progress to UI while executing.
Run Asynchronously
Easy to maintain and read.
Problems in AysncTask
When you rotate your screen, Activity gets destroyed, so AsyncTask will not have a valid reference to publish data from onPostExecute(). In order to retain it, you need to usesetRetainState(true) if calling from fragment or onConfigChanges() if calling from activity method of an activity.
If activity gets finished, AsyncTask execution will not cancelled automatically, you need to cancel them else they will keep on running in the background.
If any exception occurs while performing network task, you need to handle them manually.
Whereas AsycTask, Services, IntentService, Threads all run on different threads and all serve different purpose.
please read more detail here.
So you need to decide when to use which component while performing non UI operations.
I'm trying to optimize my android app, it's a big app and it's taking a lot of battery while running. So I'm trying to see what I can do to fix that.
I ran DDMS and looked at the threads, there are a lot : almost 30. The ones I create through instances of AsyncTask are in "Wait" state. In my code I create them, run some code in "doInBackground" and never touch them again.
From what I understand so far, it means they are done working for now, and something called "Object.wait()" on them.
So first : What is this something, how does it works ?
And : Every time I want my code to run in a new Thread, I create a new AsyncTask instance. Does this "something" wake the old thread, or should I keep a trace of the thread, destroy it when I'm done ?
Thanks for helping me understand.
The page
http://developer.android.com/guide/components/processes-and-threads.html
tells that "To use it, you must subclass AsyncTask and implement the doInBackground() callback method, which runs in a pool of background threads. "
So as a matter of fact AsyncTasks will reuse the old threads.
Hi guys am getting following error am using Websocket and Tomcat8.
java.lang.IllegalStateException: The remote endpoint was in state [TEXT_FULL_WRITING] which is an invalid state for called method
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.checkState(WsRemoteEndpointImplBase.java:1092)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.textStart(WsRemoteEndpointImplBase.java:1055)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendString(WsRemoteEndpointImplBase.java:186)
at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendText(WsRemoteEndpointBasic.java:37)
at com.iri.monitor.webSocket.IRIMonitorSocketServlet.broadcastData(IRIMonitorSocketServlet.java:369)
at com.iri.monitor.webSocket.IRIMonitorSocketServlet.access$0(IRIMonitorSocketServlet.java:356)
at com.iri.monitor.webSocket.IRIMonitorSocketServlet$5.run(IRIMonitorSocketServlet.java:279)
You are trying to write to a websocket that is not in a ready state. The websocket is currently in writing mode and you are trying to write another message to that websocket which raises an error. Using an async write or as not such good practice a sleep can prevent this from happening. This error is also normally raised when a websocket program is not thread safe.
Neither async or sleep can help.
The key problem is the send-method can not be called concurrently.
So it's just about concurrency, you can use locks or some other thing. Here is how I handle it.
In fact, I write a actor to wrap the socketSession. It will produce an event when the send-method is called. Each actor will be registered in an Looper which contains a work thread and an event queue. Meanwhile the work thread keeps sending message.
So, I will use the sync-send method inside, the actor model will make sure about the concurrency.
The key problem now is about the number of Looper. You know, you can't make neither too much or too few threads. But you can still estimate a number by your business cases, and keep adjusting it.
it is actually not a concurrency issue, you will have the same error in a single-threaded environment. It is about asynchronous calls that must not overlap.
You should use session.get**Basic**Remote().sendText instead of session.get**Async**Remote().sendText() to avoid this problem. Should not be an issue as long as the amount of data you are writing stays reasonable small.
A small part of my application checks if files exist on the user's device. The list of files is potentially quite long - apparently long enough to cause ANR's with a few users. A thousand files is by no means impossible.
The code is quite simple:
new File(fileUrl).exists()
I'm currently doing it on the main thread, as I need the operations to be blocking. I could do it using an AsyncTask class and then continue the rest of the work once it's done, but I'm wondering if that's a valid cause?
All the work is being done in a background Service, if that changes anything. I'm also potentially going to experience orientation changes, and that might be annoying with AsyncTask. Would a Handler be better?
So, to sum things up: Should I do use an AsyncTask for a potentially long-running operation in a background Service, where orientation changes may occur?
Firstly, a Service isn't affected by orientation change - it's only the currently running Activity class which is destroyed / recreated.
Secondly, an AsyncTask isn't of much advantage in a Service as it's designed to be able to interact with the UI. It would give the advantage of doing work on a separate thread but the rest of the methods would basically be redundant.
I'd recommend using an IntentService which manages its own worker thread to do work. See the IntentService documentation
I have a small Android app that I have been working on that logs GPS data to my SD card in a GPX file. I currently have a main Activity that starts a Service to do all the background work. The service is kept in the foreground in the notification bar to make it the least likely thing to be killed by the OS. Currently I am requesting location updates from the service at the maximum frequency to get the most accurate route. The problem I am having is my User Interface is acting slow/strange. Correct me if I am wrong, but what I have concluded is that I have too much going on in the main thread of the app. My next thought is to try and move the service performing the acquiring and logging of data to a separate thread. I am new to Java/Android so the whole topic of interacting with separate threads is hard for me to wrap my head around. Initially in research I came across IntentServices, which are supposed to make threading easier, but from what I read these don’t seem to mix well with the Android location package because they don’t run long enough. I feel like I am running in circles with internet searches on this topic. I desperately need some guidance on how to achieve the following features for my programs service:
Separate thread from Main Thread
Fetching and storing of data must be the least likely thing to be killed by the OS and run indefinitely once started (don’t worry about battery I will have the device plugged in to power while running the app)
Eventually I will need the ability to interact with the User Interface
Thanks for any help you can offer!
this is a common problem that i have accomplished a lot on
in the launcher or main() ( what Android is calling an Activity ) you do as little as possible ( which amounts to saving the the refs they give you and maybe setting a few other things as long as you are there ) and do ^not^ drop in to a long-running activity
A Service is exactly what you need but instead of trying to pump it into a "hold on to it" state what you do is implement checks for nulls and handle as needed -- trying to "fix" a machine to make it run the way you want here actually involves rescinding you hold on the main thread and letting it go as fast as consistent with the Applicaton's general constraints.
To do this you can simply write a Service - reading everything available - then extend that service and implement Runnable then you run the constructor on that code from the Activity Constructor and do new Thead(yourClass).start(); in the onCreate() checking for Thread.isRunning() before starting it again ...
Service will have an onCompletion() call in it somewhere - it will go through an interface
All this is done in Android in something like start activity for result then you just to the UI stuff in that call or sorta figure out a way for the GUI to get called somehow at some time then check to see if Service is done an so report in the gui