I am using getaddrinfo() linux API in my android app (in C++ NDK). Everything works fine except for one case.
If there is no internet connection in the android system, this API blocks the application for more than 50 seconds.
Is there any resolution of this problem?
A lot of posts suggest to use this API in a thread. Is that the only solution? I guess there might be an easy or alternative solution.
Try using connection timeout as the value lesser than 50 seconds.
Also, you can check network before making any API. If there is no network do not proceed. If network goes away while executing API, connection timeout will come into picture.
getaddrinfo() is a blocking API, so this is expected. You'll probably want to do task in a worker thread and/or look into using getaddrinfo_a() which can perform asynchronous queries.
Related
I am still new to android and working on an application that works on Android (API >= 21). This application displays data that is previously downloaded from a server on the local network so I need to implement a service to download the content, on-demand & Periodically, on the device.
SyncAdapter
I've implemented this "Downloader" using SyncAdapter and it was working fine but at the end the code was really verbose:
The application does not have ContentProvider. The content is downloaded as files.
It runs on a local closed network so there is no need for authentication.
The application had 3/4 extra classes that not doing any real job.
JobScheduler
After some reading and searching, I decided to go with JobScheduler.
"JobScheduler is guaranteed to get your job done." medium article
It looks easy and has clear API, I said, so I re-implemented my "Downloader" with JobScheduler and the result was really good. The application was able to download the content, writing a good log to trace errors and operations. The Job runs when the device is Idle and kicks off/stopped, on demand, as expected.
I used alarm manager to implement the periodical calls of the job and turning wifi on. Oh, I forgot to mention that the application is the responsible of turning on the wifi because it is inside a case and works as Kiosk
The problem is that there is a catch. This is not mentioned in the documentation, or I was blind not to see it, at all. The Job is limited to 1 minute only (1 minute on lolipop and more on Android >= 0) then the onStopJob() will be called. So my is cancelled before completing the download when the data is a little big. Of course I can keep my thread going and continue download in the background but in this case I can't benefit from the API to maintain a good log, reschedule my job and manage Wifi status.
I need another implementation
I need something similar to SyncAdapter or JobScheduler that runs when the Wifi is on and when the device is Idle.
I am not sure whether triggering a service from JobScheduler is the solution I am left with. I need a little certain information before implementing the same thing for the third time.
Any idea?
I am a Java developer with no Android experience, and I am trying to quickly put an app together. It seems that what I would normally do in Java isn't helping.
At this stage, ease of implementation is more important than efficiency or style - I will sort the latter out when there is more time and I will have educated myself properly when it comes to Android.
People can use the app to ask for support, or offer it to those who need it. Asking for support posts a request with the details to the server, and that's done.
Now I would like the app to post an asynchronous request to the server, to be notified of outstanding support requests once a minute. I guess it's the same principle of WhatsApp checking if there is any new message on the server.
I tried doing that in a separate thread with an infinite loop which sleeps for 60 seconds but for some reasons that stops the UI from working.
From what I now understand, I should use a service with a Looper, a Timer and a Handler. Is that correct?
Could anybody point me to a tutorial which explains exactly what to do, step by step? Or at least suggest keywords I should look for?
All I found so far are snippets of code which don't work together when I try to assemble it. Possibly because I am not searching for the right terms?
Thanks, Dan
You could try the following approach:
Create a service that runs in the background to check for newly added data in the server.
If you prefer to make it user-driven, you can let users refresh the list on the device to actually trigger the requests to the server.
Libraries like Retrofit can make your life easier when it comes to making http requests - always avoid the main UI thread when doing this.
Another library that you could use to decouple your application using Events is EventBus. Assuming you are running a background service to check for updates, you can use EventBus to update your User Interfaces when something new is retrieved from the server through a GET request.
I hope this gives you an idea on how to proceed with the solution. Good luck!
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'.
I have created a webserivce using C# on .NET and I'm consuming the same in an android application. At times while testing I notice that the web service is annoyingly slow and does not show results for minutes altogether. I don't want to put my user through this behavior of the application.
I am basically looking for a way such that the communication between the application and the web service can become faster.
PS: I am using asynctask function already to provide a separate thread while calling the web service. STILL it takes minutes at times to extract results from it.
Any help is appreciated!:]
I can't tell if you're saying the web service is slow or if it's just slow to be consumed on an Android device.
If the web service is slow on all devices I'd suggest first eliminating the possibility that it's just the speed of the web connection you're testing on. Obviously there isn't much that can be done about that. If the service is simply slow to respond I'd recommend running some profilers to determine where the slowdown is. If it can't be made more efficient perhaps this is a task better suited to be first requested and placed in a queue. When the task is complete alert the device that the data is ready.
If the Android device is slow I'd also recommend some profiling to determine what's eating up the processor.
Sorry if I'm stating the obvious here but these are the only options I can think of.
I'm currently trying to assess whether a project can be realised for Android. One major problem I see it that, since it's a P2P client, we'd have to keep a considerable amount of connections open when running. Now the connections do not transfer large amounts of data, it's more of a messaging system, so having a thread for each connection creates a useless overhead if we're reading a single message of 64 bytes every now and then.
So I was wondering whether there is support for non blocking IO such as select() or poll() on Linux.
Any suggestion?
Check out java.nio Sockets, Selectors, and Channels. Some links:
Android: Unbuffered IO
http://developer.android.com/reference/java/nio/channels/ServerSocketChannel.html
http://developer.android.com/reference/java/nio/channels/SocketChannel.html
http://www.developer.com/java/article.php/3837316/Non-Blocking-IO-Made-Possible-in-Java.htm
Or, maybe I didn't read your question right.
Of course. Once your application declares uses internet permission, you can do all normal linux networking things normally available to a non-root user in C using the NDK, and any of them from java that someone (possibly you if no one beat you too it) has bothered to write support for.
Well, one exception: your mobile provider probably won't permit incoming connections, and neither will most wifi routers unless you specially set them up to. But those are infrastructure issues rather than issues with android itself.
You will probably also need to come up with some combination of an Activity to provide the foreground UI and a Service to continue the actual transfers in the background with just a status bar icon showing.