I am sending data via broadcasts like this:
Intent outIntent = new Intent(Const.ACTION_FEED);
outIntent.putExtra(Const.EXTRA_FEED, data);
sendBroadcast(outIntent);
The issue is that data can get quite large, resulting in a TransactionTooLargeException. The documentation says:
The Binder transaction buffer has a limited fixed size, currently 1Mb, which is shared by all transactions in progress for the process. Consequently this exception can be thrown when there are many transactions in progress even when most of the individual transactions are of moderate size.
Bottom line: it seems to be impossible to tell in advance what size is acceptable for data.
Furthermore:
The key to avoiding TransactionTooLargeException is to keep all transactions relatively small. [...] If possible, try to break up big requests into smaller pieces.
The nature of the data I am sending is such that I could easily break it down into smaller pieces and send them individually, once I have established that the whole thing is too big to send at once.
The logical step would be to wrap the whole code in a try/catch block, and upon receiving a TransactionTooLarge exception, chop up the data into smaller chunks and retry.
Alas, according to the logcat, the exception is not thrown at the caller’s end but in a system process. The system then goes on to crash the receiver of the broadcast, at which point any recovery is out of the sender’s control.
How can I tell how much data is OK to send as a broadcast extra, and prevent crashing the receiver of the data?
Related
in the App i am developing, i have a a layout with 6 TextViews, these textviews wil display data received at very high rate from a server. so far, i set the
values i receive to the textviews, but when i run the App. the data that textview displays are changing very slow because of the values sent at very high rate.
for an example, the server send almost 100 line in one second, and the datat in this 100 lines should be displayed by the TextViews..but because, as you noticed,
the high rate at which the dtat is being sent, the TextViews cannot show all the data by the time they sent.
What i want to do is, to be able to display these frequent data using the textViews but without lagging or delay in display the data, something like how do you see
the sensor data displayedin a textView.
given the above issue, does using the handler might help?
given the above issue, does using the handler might help?
To answer your question, this is what the docs say in regards to Handler:
There are two main uses for a Handler:
(1) to schedule messages and runnables to be executed as some point in the future; and
(2) to enqueue an action to be performed on a different thread than your own.
Honnestly, I don't see how the Handler could help you achieve what you are looking for.
Do you make your http request in a separate thread? (if not, then you should)
Also, I am not sure I understood the connection between the TextViews and the very high rate from server.
The handler is only a means of enqueuing a Runnable to be run in the Main Thread. You shouldn't plug the output of the server directly to the GUI, because you might be clogging up the main thread.
If you are downloading at high frequency, I'd suggest storing the downloaded data somewhere in memory (or persistence if needed), and have the GUI read this intermediate data at a slower pace.
I have an Android app from which I receive BLE data (every 62ms via notifications). The app can save data via a BufferedWriter to a file. Upon ending the save of large amounts of data, I see an error such as this: GKI_exception out of buffers https://code.google.com/p/android/issues/detail?id=65455 (except my code is not scanning but receiving notifications). I don't see this error for 100s of kB saves, but I see it on 1-2MB saves in logcat, and on >5-6MB saves I need to power cycle the Nexus 7 (the app and BLE become totally unresponsive). I call close() on the BufferedWriter at the end of the save. How do I fix this?
The issue is likely thread related. You need to make sure that the "save" operation (which is writing file data to disk...an operation that takes a long time) is not happening in the same thread context that could block your BLE notifications or a related callback. If you block a thread that keeps a BLE callback method from returning, you will see the Bluetooth stack get starved, which is what that callback usually means.
Simplest thing is to always make sure you write file data in a new background thread (like an AsyncTask, Thread, or IntentService for instance), ensuring that regardless of what thread you were coming from, the long write to flash memory won't block the current context.
I have quite much data to send to a server. The format is JSON and my platform is Android. I was wondering would it be wise to somehow divide the data in smaller packets, or send all the data at once? Also would it be good idea to run the sending code in a different thread? I use HTTPPost to send the data with Android
Creating smaller packets will cause a lot more overhead, thus a lot more data to send. Also, all networking should be executed on a separate thread (not UI thread).
Whether to use "many" HTTP requests or just one depends on your program flow. On one hand, you don't want to send data over the network that you are not sure you will need, so one catch-EVERYTHING post may be a bad idea. On the other, reducing the number of requests is going to reduce the overhead associated with each one, and thus result in less total time spent sending.
And yes, always perform network operations outside the UI thread. As far as the rest of the system is concerned, these are intolerably slow.
In my application I want to pass an ArrayList of Parcelable objects (or a Parcelable[]) between two activities. On the first activity i call a restservice to get the json data, after that I use gson to get the List of Parcelable object and then i send the list to the second activity using putParcelableArrayListExtra(...). All works fine until the size of the list is about 1000, but over this size I get an ANR and application won't resume even if I wait for some minutes.
Is there a solution for this issue maintaining this approach? Is it due to a size limit for object put to an Intent?
I know I could pass the Json String and then get the list on the second activity, but I prefer to make first this kind of operations.
First off, ensure that the source of your ANR is indeed the large parcelable object, and not because you were performing a blocking operation (i.e. networking) on the main thread.
Now if the ANR issue really is due to these large objects, the right way to get this done is to deserialize the object and write it out to storage instead of passing it between activities. You're effectively doubling the amount of memory you incur by doing what you're doing.
Here are a few ways you can troubleshoot this:
StrictMode: StrictMode is most commonly used to catch accidental disk or network access on the application's main thread, where UI operations are received and animations take place. By keeping your application's main thread responsive, you also prevent ANR dialogs from being shown to users.
Traceview: Traceview is a graphical viewer to see logs created by an Android application. Via Traceview you can find errors in your application and measure its performance.
Memory Dump: You can create a memory snapshot and analyse it with the Eclipse Memory Analyzer.
New to stackoverflow, been very helpful searching, but alas the time has come to ask a question.
I am trying to use an android 2.2 single core phone to do some research. I have implemented an algorithm that does quite a few calculations and produces a lot of data. These data must be processed, and the solution presented back to a client app within a 40ms time frame, then process again with new state data coming from the client. Also, the result of the calculations must be stored to the SD card as a data log. So being new to multithreading and android both, what should I use to do the following in my app: (As a side note, this phone, when in research mode is not intended to be used as a phone, phone will be in airplane mode with wireless off, and all apps that can be turned off will be turned off, and there is no need for UI display or interaction once it is up and running...)
need to process packets coming in over adb on serial port, these packets are state data that the program needs to perform its calcs on. These packets will be coming every 40ms, so I planned on using their arrival to trigger the start of the processing.
need to know if the algorithm is taking longer than 40ms and cancel it if so and send a message back on the serial port that it overran.
the calculation results need to be sent back over the serial connection via tcp and adb
The calculation intermediate data need to be recorded to SD. This can be quite a lot of data, on order of 140k, every 40ms.
So I have had trouble getting all the pieces together. I can't get my head around how a single core is going to keep up with all this going on at once?
So here is my thought, please tell me if I am headed in the right path. I am not asking for you to solve my problem, only any advice on how to break this beast down:
So i start a service to process the tcp packets coming in from the client
Use a service bound to the main worker thread to handle writes to the SD card
So assuming this setup, can i make the algorithm part of this somewhat deterministic so that it always runs if it gets a new tcp packet, and preempts the SD write going on in the background?
Argh...should have picked something simpler for my first program
Thanks.
Yes I think you are right, that it would be better to pick something easier for your first App ;)
But as far as I understand what you are trying to do, I don't think, that you need asynchronous multiprocessing. You get some data want to process it and pass a result. I think a HandlerThread is exactly what you are looking for. It is able to recieve Messages
with data inside. You send them to the Handler and process them in an overridden handleMessage(Message m) method. So everytime you recive a Message you could just log the Time
and see if the last one is older than your limit. If it is, you could just throw the Message or the whole queue, or send a Message to your serial-port inicating the overflow.
This could be implemented as you suggest in a Service. Another HandlerThread can be started with Thread.PRIORITY_BACKGROUND to write everything to SD.
You can send Messages even very compfortable if you apply a Messenger to the Handlers