In my android application in java, I am doing an http async request then I want to print the result in a TextView that is in a ScrollView.
This work fine when the result to print is short. But it can be very long and then the application is freezing for ~3-5 second.
I know this is because to much work is done on the main thread but is there a way to set the text of a TextView on a separeted thread ?
To illustrate this is my code in the onResponse of the httpRequest :
tView2.setText(requestName);
tView3.setText(message1);
tView4.setText(messag2);
tView4.setText(resultBody);
tView5.setText(message3);
If i just remove the line
tView4.setText(resultBody);
(where resultBody contains a long String) The UI does not freeze any more, and the other message are print almost instantly.
But when I let it the UI is freezing even before the print of the previous message so I can't even set a message of information preventing the user that can take some while (what I tried in my code, it's why there is 2 setText on the tView4)..
What I want is the simpliest solution to manage that. So an easy way to print a message of information to prevent the user would be good.
Thank you.
Related
I'm reading Sensor Data from Device Sensors(Multiple Sensors) and call a Method to show the data I received from sensors to the designed TextView.
The method I'm calling to update TextView:
private void UpdateDataStream(String _Entry,Boolean isAppend)
{
if(isAppend)
ViewHolder.append("\n("+sensorName+")"+_Entry);
else
ViewHolder.setText("("+sensorName+")"+_Entry);
}
Method called from SensorEventListener's , onSensorChanged Event.
What I couldn't figure out is how to prevent freeze while updating TextView; since sensor data update is intensive(considering it is from multiple sensors simultaneously) updating TextView cause Application to freeze or crash. I don't need to "print" every data I received, like It is enough for me to print for every 1-2 second, lost data can be ignored.
Is there any approach/patern or built-in structure to achieve this ?
(I'm new to programming in Java&Android, yet I'm familiar with multiprogramming, parallel programming concepts, yet I couldn't figure out how to apply them in this environment)
This is fastest solution:
https://github.com/ReactiveX/RxJava
http://reactivex.io/documentation/operators/debounce.html
Or you can:
create stack (for example)
write sensors data stream to stack from thread#1
in another infinite loop thread#2 read last data from stack every N time (don't forget to synchronize them)
clean the stack
write last data to TextView (don't forget to set text in ui thread: textView.post( () -> textView.setText("safe call") );
This relates to this Java question.
Here's my problem. I've written an app that allows people to do a lot of data entry, typing into a lot of separate fields. To confirm the change in each field they can often hit Return (for a single line field) or control-S (for multi-line fields where Return would be valid input), but that's cumbersome, so I also allowed fields to save their content when they lose focus. So users can type-tab-type and it all goes smoothly.
Except if they change a field and then click on the application window exit X in the corner. They expect that this counts as losing focus and will save that last change. But the lost focus event doesn't happen and the change is lost.
I could add a Done button, which would have the side effect of moving focus and saving the last field, and then exiting. But I shouldn't have to. There's a X in the corner and it should do the right thing.
My first thought was
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(.....
because I thought from there I could publish() something to my SwingWorker to tell it call loseFocus on everything. No such luck; publish() is protected.
Basically I need to do one last operation on my various widgets when X is clicked. How do I?
Edit: I should note that each editable widget (dropdown, JTextPane, etc) has been extended to hold the actual relevant data. All the data for that widget, e.g. whether the value the user typed is valid, what it was before he edited it, etc. is in those extended class instances. There's no other place values are held; this isn't model-view-controller.
The reason for this is that widgets can get changed either by user actions or network messages; a message can come in that throws out an existing widget entirely and replaces it with one with new content. In other words, doInBackground is in a permanent read-loop, reading network update messages and publish()ing those update requests to process(). User action happens as usual, between calls to process().
Bottom line,there's no global data structure to go to at exit time to get values. They're all in dozens to hundreds of data structures managed by the swing worker thread.The app itself, outside that swing worker thread, doesn't even know what sort of values and widgets exist - all widgets are created, placed and destroyed by network messages from the server. The rest of the app (what little there is) couldn't safely get to the data if it wanted to, unless I implemented a whole lot of shared data and locking.
It all works flawlessly, and I'd rather not redesign it all for this one tiny shutdown case. It just never occurred to me that I couldn't publish an extra "shut down" message into the work queue for process() from outside that thread. (I mean thread safe queues are trivial to implement; why didn't they?)
If the answer is "you can't talk to swing at shut down", I'll live with it. I do have a potentially evil workaround - I could have x do nothing but send a message to the server, which could write back a "you should shut down message" which could do the rest. But that seems ungainly.
The short answer is, there isn't a good solution. I tried installing a shutdown hook and publishing a message to the swing thread to tell it to finish up, and then gave the shutdown thread a 500ms sleep to give process() time to happen. process() wasn't called. publish() alone apparently isn't enough, once shutdown starts.
Bottom line, don't put data you need to get at in swing threads. Global data and synchronized functions is the only way to go.
My code retrieving on AsyncTask data from cloud database.
I have notice, if I am putting break point(while debugging), My code runs ok, the data received and then my code manipulate that data.
If I am not using any break point my array is null, the code did not wait for the data to arrive.
I have tried,
Thread.sleep(timeInMills);
and
SystemClock.sleep(timeInMills);
but this did not help, It seems to stop the entire Thread.
Is there a way for me to stop the code the same way break point does for a second or two.
Again this does not effect my UI Thread as this run in AsyncTask.
i have faced a similar situation
if you send the result array to an adapter or a function make it execute at the end of onPostExecute method , as before that your data Array would be empty
I am using Crouton as alternative to native android toasts. I have to display 5-6 croutons one after the another and then call System.exit(0) to exit my app.
The problem is, I see first crouton for 1-2 seconds and the app just exits! The rest croutons aren't displayed at all. This is because when the code is being executed the undisplayed croutons are added to queue. And when it comes to System.exit(0) it exits the app without displaying those queued croutons. I have tried searching for solution for this and came across a solution in which I have to create a new thread, then sleep it for time = sum of durations of necessary croutons and then call System.exit in that thread. But then if I have more or less croutons in another situation then that becomes useless.
So can anyone think of a solution?
Why do you have to quit the app?
In general, in Android, applications should not quit, and show not provide a way for the user to quit them. Quitting an app is handled by the system when the user navigates away from it and goes back to the home screen.
If your application must quit (for example, because of an unexpected condition it can't deal with) and you want to make sure the user sees the information, then the best approach would be to use an AlertDialog to display the information.
So, long story short: revise your UI... if you're sure that this is the right way to do it, then simply don't call System.exit(0). Just show the toasts and then stick around. Eventually the system will decide to quit your app when memory is needed.
I have some questions about executing SQL queries (to an online database) from an Android app.
Since these are network operations and they are costly, should I be doing them in a separate thread? Also, what should I show the user (UI) while these queries are processing?
I suggest you to make a use of AsyncTask. In the doInBackground() method you'd be downloading/processing stuff. In the onPostExecute() you'll be displaying on the UI. This is in short. Research base on AsyncTask for further information.
The first answer is good with regards to AsyncTask. If they're REALLY long queries, I would put them in a service and communicate back to the activity with a broadcast, but if they're just "network long", then Async is good.
It seems like EVERYBODY wants to use a waiting dialog, but this kind of UI generally sucks. It blocks everything, so if you can't get a response or whatever, the user is stuck. I recently reviewed an app for somebody, and because our network was slow, the time spent waiting in an alert box was 47 seconds. Any idea how long that feels to a user?
I would disable a repost, put some kind of spinner up, but don't block the UI. If the user wants to do something else, let them. Also, when the AsyncTask comes back, the screen that it expects to manipulate may no longer exist. Wrap everything in case you get an exception.
I try to do all remote stuff in a service, even if it isn't totally necessary. Talk back and forth with broadcasts. That's just me, though ;)