I have built an Android chat application. It has a TCP server which is connected to via using a Socket.
I want the server connection to work in the background always - even if the app is not in foreground - and listen to data sent from the server.
For now I am using a while loop to checking if there is something new, but the OS close my thread when Android needs resources.
I have thought about using the readline() method in my thread instead of using the while loop because readline() is a blocking method.
Is this the right approach to take, which will lead to, prevention of the OS from killing my application?
Is there any way, like a custom broadcast receiver that will launch only when the incoming socket is available?
Thanks!
In short, Android can and will kill any applications that hog up resources in order to keep running. The onus is on you on how to handle the scenarios which can threaten your app to be killed.
I suggest looking at the service's life-cycle as found on the developer's site.
For a start, any application, be it service/activity, that hogs up too much, in this manner is considered... "rude" in the eyes of Android, and therefore, is prepared to be killed in this manner regardless!
For example, listen in the onLowMemory override method and act accordingly, such as saving data and what-nots.
What really, should be happening, is this, the service, spawns a thread to periodically listen for incoming connections in this manner,
while (!terminating){
Socket incomingClientSocket = ourServerSocket.accept();
// How you handle this part is up to you?
Thread.sleep(500); // Sleep for 500 ms
}
The terminating variable is a boolean and is the deciding variable that controls when to terminate the loop. Notice how the Thread.sleep method is used, to "calm down" the execution, if omitted, Android will put a cross-hair on the app and terminate it, in other words, be polite to system resources.
Hint: Extend the Thread class, to hold the functionality of handling incoming connections via the accept() method.
When the incomingClientSocket becomes non-null, then another thread is created in which it opens the input/output stream of the incomingClientSocket and read/write to it using binary fashion.
Do not use the readline method as that is an indication of poor design and assuming the data is text-ual, because one incoming packet to the client could be for example, 720bytes, the next packet coming in after that, could well be 564 bytes, that is the nature of TCP/IP.
You need to come up with a more reliable way of establishing boundaries for the data transmission, for example, a begin and end marker, and let the server read the incoming data and distinguish the byte stream that composes of a begin and end markers, once both are present, then extract the real data in-between the markers and act on it accordingly.
You could for instance, say, upon incomingClientSocket that actually becomes non-null, send a broadcast to your activity to act on it, and let the activity, take that socket, and open the connection and read/write to/from the input/output streams associated with the socket.
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 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.
My app has a UI and a connection is made to a bluetooth device which is periodically sending barcode scan data to my app. I then want to cache this data in a sqlite db and have another process push this data up to a web server.
I have managed to get the UI and bluetooth scan process separated by using an Intent Service for the scanner component... The thread in the intent service connects to the bluetooth device and loops endlessly pulling in new scan data as it comes... communicating with the UI via broadcast messages as it needs to.
So now I need to handle storing the data in a sqlite db and pushing it up to the Internet.
I'm thinking I can insert a db row directly in the intent service loop I already have working for the bluetooth data... would I do that by firing of an async task or something like that?
Then, would I have a completely different intent service running and looping endlessly checking for new records to be processed and pushed up to my web server via an http post?
I guess the main reason I'm thinking of using intent services is that they seem to keep running even if I lock my phone and put it in my pocket... has worked so far for the bluetooth barcode scanner... can scan away happily with my phone locked and in my pocket.
I also need to handle the reality that internet won't always be available... hence the sqlite db... kind of like a safe buffer to store data until it can eventually be pushed up to the Web server.
Am I going down the right path? I'm really new to Android development and even after much research I'm still unsure about my approach.
You can store data or communicate from IntentService onHandleIntent() directly. You don't need to run it in separate thread, unless you want reading bluetooth to continue ASAP.
Handling everything in an infinite loop smells. Also keeping service alive depends on few factors. If IntentService dies, it won't be restored because by default IntentService.onStartCommand implicitly returns START_NOT_STICKY, or START_REDELIVER_INTENT if you call setIntentRedelivery(true) on this service. Check Service javadoc for more info.
If you can scan bluetooth periodically then I would consider kind of scheduler. For that you would probably need to implement Service, not IntentService and handle background thread yourself. Alternatively, you could use a Timer. These are more hints, not ready solution. Since you asked about direction, I assume you will investigate solutions yourself.
Depending on handled data you could separate DB operations and network to separate services. Think about them as modules which are decoupled. You will benefit maintaing this code in the future and in case one service goes down due to any reason, the rest will keep working. It depends on data size because it's not a good practise to push heavy data between service/activities(data is serialised and deserialised every time it is sent).
If DB is just a buffer/queue then maybe use it directly after reading bluetooth data. In other words queue data for sending. Create second service for HTTP communications. Don't push entire data to second service, just inform it about(knock the door :)) and let HTTP service access DB by itself. I would wrap DB in ContentProvider and access it from services.
There are probably different techniques out there too, but that's what I thought about it in the first place.
I have been doing some research lately over my work project, i am trying to read card swipe data from Bluetooth card reader in my app.
So as to get that data i have to use thread, i know the reason why is there a need to use so as this process does not hinder interface activity, but here my concern is not to handle interface activity at the time of fetching data. But threading makes sense when there is a need of BluetoothServerSocket so as to have full duplex connection.
So my question basically is that if i am just receiving data from remote device do i really need to have a BluetoothServerSocker under Thread?
When you are doing some action that is going to take some time in performance, then it is better to use Thread. When you are reading Data from Bluetooth Card Reader, then in this case, in background many activities take place. for e.g. Bluetooth Connection, Device Discovery, Pairing, Asking for permission , retrieving data. It may be possible cause of device hang or user may not like to be in wait state. so to prevent such cases it is better to use Thread.
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