I am currently using an InputStream in my application (import java.io.InputStream) and have run into an issue regarding timing out. The way the InputStream seems to work is that it waits for a certain amount of bits and then proceeds. For my application this works a lot of the time, but there are cases where I am expecting the read to fail due to timeout. Does anyone know a way to do this?
I have found many examples of creating threads to run alongside the read() function and cancel it, but I was wondering if there is an existing class which lets me use an InputStream that times out.
This largely depends on where you are reading from. If it is from a file (or local) socket, there is no timeout. If it is from a remote socket, you can specify timeout when creating the socket. If it times out you should get an exception. Using threads/AsyncTask is the way to go, but you generally cannot interrupt a blocked read, unless you are using Java NIO.
And no, it is not ridiculous, how do you propose for it to 'time out on its own'? Someone has to signal the timeout, and that someone is either some sort of monitor thread or the OS raising an error.
I would use AsyncTask<> for this. You can try to start reading the stream asynchronously and then at a time of your choosing cancel the task, rather than blocking your UI. Documentation here
Related
I have an app (Android Studio) that continuously generates data (Joystick coordinates) based on the user touch, that I want to stream continuously to my NodeMCU using Socket programming. I implemented an Async Task to do this on a separate tread.
I pass the bytes of data to the AsyncTask via execute() method from the Main Activity. The doInBackground method opens the socket connection and transfers the data byte to the server and then closes the socket. With the next available user input this process gets repeated again. Now for obvious reasons, this is not very effective.
I haven't figured out a way to keep streaming the bytes from the Main Activity to a buffer on a separate thread which would in turn keep streaming the bytes to the NodeMCU without repeatedly closing the socket.
So here is the question. What would be the best solution for my problem? I have been reading about so many different things like Services, Threads, Loopers, RxJava and it seems I am getting no where.
Well my Preferences would be:
RxJava - because RxJava is supercool, solves a lot of problems like switching schedulers between UI and IO and is close to your domain. Think of your joystick device as an Observable constantly emitting events (thats exactly whats RyJava is good for).
Services - can be done efficient. It will come down to an Observer-Pattern provided by the Service. In Android its is common to expose some hardware through services.
Loopers - because they are a little more lightweight and easier to manage than Threads.
Threads - possible, but probably most work to do on your side and most likely to produce subtle bugs.
I have to send four different request in an api at the same time. Do i need to make AsyncTask background thread for each request or all request could be done through a single AsyncTask. Can somebody please help.
This is a concurrency issue. There is literally dozens of ways to do this in Android. I've written almost every single one for courses that cover this material... and even then it isn't 'simple'.
I'd personally make use of HaMeR (Handler, Messages, Runnable) framework of Android. Create 4 runnables and have them post their results to a Handler.
However... That isn't the easiest to implement. and would require you to understand how to safely create your own custom handler (making use of WeakReference properly, etc.)
Therefore, I'd recommend running the asyncTask(s) on the executorService
myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); The default thread pool executor should start with 4 threads (I believe off-hand without looking it up).
I am assuming you are using HttpURLConnections. Unfortunately each of those connections, as specified in the documentation, is capable of handling only a single request.
However, you can (and possibly should) still perform all your requests in a single AsyncTask. Each AsyncTask will require the creation of a new thread which takes lots of time and resources. So don't listen to anyone who tells you to create a new task for each request.
You also have the option of exploiting HTTP persistence. If you add the header Connection: Keep-Alive to your request via connection.setRequestProperty("Connection", "Keep-Alive");, you will be able to send multiple requests over the same connection and save a lot of time and resources.
It's a little complicated in Java, because of the one-request-per-httpurlconnection rule, but it can be done. First, when you are done with your first request's HttpURLConnection do not close that connection. Then, to create the next connection, call url.openConnection() on the same URL object that you used to create your first HttpURLConnection. The JVM will know to reuse that connection if possible to save bandwidth.
You also have the option of using HTTP/2.0 multiplexing, which allows you to send multiple requests literally at the same time. Unfortunately I am not yet well versed enough in HTTP/2.0 to tell you exactly how to make use of this, but the multiplexing feature was included to solve exactly this problem.
My Android app makes three distinct forms of data transfer:
Queries the local database: returns results if found (local / short timeout);
Queries a remote API: typical response size is around 1k (remote but tiny payload / medium timeout);
Downloads a remote file: size may be anywhere between 100k - 1MB (remote and large data / long timeout).
These transfers are made using extended subclasses of AsyncTask and they work pretty well, certainly for steps 1 and 2. The issue is with step 3.
If the device is on WiFi, 3G or another reasonably fast connection, the AsyncTask will not time out and the remote file downloads in time. If the device is on 2G or a slow connection, it will time out - even when the download is still progressing (albeit slowly).
Ideally, I would like to monitor the download progress at intervals, and either reset the AsyncTask's internal timeout counter or prevent the task from cancelling if progress has been made since the last check. Unfortunately, both of those options seem to require either read or write access to AsyncTask's private timeout variable.
How can I prevent AsyncTask from timing out when download progress is still continuing?
Edit: I've just noticed that StackOverflow offered me the tag of Android Download Manager. Is this the kind of thing that ADM is designed for?
I'm going to answer my own question here, or at least the edit, to say that in the end I implemented Android's DownloadManager to ensure that background downloads could continue at whatever pace the connection allowed. I then implemented a Manifest-declared Receiver which started a Service to insert the response into the database. Finally, the user is notified via the toolbar that the download has finished and that they may return to the app to view the results.
However, I'm not going to accept my own answer :-) because I haven't answered whether it's possible to stop an AsyncTask timing out in the way that I asked. But everything I found suggests that the answer is 'no'.
My app displays data from a steady stream of Bluetooth text input.
In Android 2.3.4, if I close the socket the read immediately throws an IO exception. In 2.2 is does only most of the time.
I am trying to stop the reading when onStop() is called. Then in onStart() I reconnect.
Is there a better way to kill the thread that is suspended on an inputStream read that is likely to work over all versions?
Thanks
TomZ
I tried interrupting the task and got bogged down in multiple types of exceptions depending on what it was doing at the time of the interrupt and getting compile errors that I was catching exceptions that it said could not be thrown. Even when I did get some working code, it still had reliability problems on Froyo (Galaxy S - Vibrant).
So I backed up and tried using InputStream.available in a loop with a short sleep and a check of a flag that is set to end the read task (so the task was never suspended except on the sleep). This worked great on various android versions.
It seems the trick is to not externally stop the thread but to let it detect the need to quit and return on it's own.
Seems a bit of a kludge, sort of polling the reads. But the code is now stable and the phone performance does not seem to suffer.
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