I'm creating and android program which needs to to continuously keep sending data over the bluetooth now I use something like this:
for(;;)
{
//send message
}
though this works it freezes my UI and app how can I implement the same without freezing my UI?
I am sure that the app is sending the data as I monitor the data.
Put your loop in an AsyncTask, Service with separate Thread or just in another Thread beside your Activity. Never do heavy work, infinte loops, or blocking calls in your main (UI) Thread.
If you are using kotlin then you can use coroutines.
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.4"
initialize a job variable job:Job globally
then do:
job =
GlobalScope.launch(Dispatchers.Default) {
while (job.isActive) {
//do whatever you want
}
}
Do job.cancel() when you want your loop to stop
You need to move the work into another thread (other than the UI thread), to prevent ANR.
new Thread( new Runnable(){
#Override
public void run(){
Looper.prepare();
//do work here
}
}).start();
The above is a quick and dirty method, The preferred method in most cases is using AsyncTask
Start an IntentService which will create a background thread for you to run your Service in. Call Looper.prepare() as #YellowJK suggests, but then call Looper.loop() when you need your program to wait for something to happen so the Service isn't killed.
#Override
protected void onHandleIntent(Intent arg0) {
Looper.prepare();
//Do work here
//Once work is done and you are waiting for something such as a Broadcast Receiver or GPS Listenr call Looper.loop() so Service is not killed
Looper.loop();
}
Related
This is not the problem about being able to call a method in the main/UI thread but being able to do so instantaneously.
It is my knowledge that you are not normally allowed to interact with the UI thread directly because of the UI responsive requirements. It would make sense then to have a system in place to queue the requests you have for the main thread and we do have that system with the looper, handler, etc.
Here is what I did:
I did some task in the background thread and I want to intimate the main thread as soon as a condition gets satisfied(I created a listener for it) and I use the response handler to post it..something like this:
if(mNoOfPendingRequests >= mNoOfRequestsConsideredEnough){
mShouldFlagEnoughRequestsAtATime = true;
Log.i("ThumbnailDownloader: ","Enough Requests Queued");
//Now inform about this to PhotoGallery right now
mResponseHandler.postAtFrontOfQueue(new Runnable() {
public void run() {
mEnoughRequestsListener.onEnoughRequestsQueued(mShouldFlagEnoughRequestsAtATime);
}
});
}
else{
mShouldFlagEnoughRequestsAtATime = false;
mEnoughRequestsListener.onEnoughRequestsQueued(mShouldFlagEnoughRequestsAtATime);
}
If I don't inform the PhotoGallery about the enough requests sent already, it would continue to send more and more requests and app becomes unresponsive.
Also, the requests are queued and are executed later resulting in too many requests.
My question is therefore:
Is there a way to call a method/inform in UI thread from a background thread almost instantaneously?
You can run things on UI thread doing this:
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
// put your code here :)
}
});
Is there a way to call a method/inform in UI thread from a background thread almost instantaneously?
Not really. Your postAtFrontOfQueue() is about as close as you can get, and as the boldface note mentions in the docs, "This method is only for use in very special circumstances -- it can easily starve the message queue, cause ordering problems, or have other unexpected side-effects."
If I don't inform the PhotoGallery about the enough requests sent already, it would continue to send more and more requests and app becomes unresponsive. Also, the requests are queued and are executed later resulting in too many requests.
Have more smarts in your queue, to know when to throttle back request processing based upon whatever your "enough" algorithm is.
This method works like a charm unless you already have lots of events in your events queue.
activity.runOnUiThread(new Runnable() {
public void run() {
// call your method here
}
});
Yes, you can call using activity context
runOnUiThread() and pass runnable object and write code inside run() method.
It is not clear from your code, what onEnoughRequestsQueued does. If all it is doing is telling the posting thread that it should stop sending requests, then you can probably accomplish the same thing with a simple volatile boolean
If the thread enqueuing requests stops doing so, when the variable is true, and the background thread sets it true, and the variable is volatile you should be good.
I've got this piece of code:
public void updateOptionLists() {
Log.d("UI", "Called update");
if (updating){
return;
}
updating = true;
runOnUiThread(
new Runnable() {
#Override
public void run() {
updating = false;
updateOptionList();
scrollToLastTapped();
Log.d("UI","Updating");
}
});
Log.d("UI", "Posted update");
}
What I'd expect from logcat would be something like this:
Called update
Posted update
Updating
As far as I know runOnUi should be asynchronous, right? And considering that the functions called alter the views, which takes a while, this should be running asynchronous. Right?
So I look at my logcat:
Called update
Updating
Posted update
Why does this happen? And how do I make sure this runs asynchronous?
runOnUiThread will execute your code on the main thread, which (in this example) also appears to be where it's called from. This explains the ordering of the log statements you see - all code is executing on a single thread, so is synchronous per the documentation (my emphasis):
Runs the specified action on the UI thread. If the current thread is the UI thread, then the action is executed immediately. If the current thread is not the UI thread, the action is posted to the event queue of the UI thread.
runOnUiThread is typically used to execute code on the main thread from a different (i.e. background thread). The use of this separate background thread is what will make a task asynchronous. Calling back to the UI thread at the end of that task is required if you want to modify UI with the results of your background thread calculations.
Android provides several mechanisms for doing work on a background thread and then posting back to the main thread (not all use runOnUiThread explicitly for the latter operation). Good things to read up on include Thread, Handler, AsyncTask, Service, etc.
As far as I know runOnUi should be asynchronous, right?
runOnUiThread, as the name states, runs on UI thread, which is a main thread of an application. It runs synchronously with other code running within that thread and asynchronously with code in other threads.
The word 'asynchronous' has no meaning without a context: some code can run asynchronously with other parts of the code, which means these parts of the code run in different threads. Saying that something 'should be asynchronous' makes no sense without this kind of context.
is updateOptionLists running on the UI Thread?
If this is the case, i would expect this behavior to be ok.
In a normal case you use runOnUiThread from a background thread to come again to the Ui Thread..
Because you call upadetOptionLists() on ui prosess, upadetOptionLists() and runUiThread() both run in the same thread.
To separte theam you need run content in other new thread as following
public void updateOptionLists() {
new Thread(new Runnable() {
#Override
public void run() {
Log.d("UI", "Called update");
if (updating){
return;
}
updating = true;
runOnUiThread(
new Runnable() {
#Override
public void run() {
updating = false;
updateOptionList();
scrollToLastTapped();
Log.d("UI","Updating");
}
});
Log.d("UI", "Posted update");
}
}).start();
}
For accessing the view, you must be in the UI Thread (the main one). So, runOnUiThread will be executed on it.
You must do the long work in an other thread and only call runOnUiThread for little thing like changing a color or a text but not to calculating it.
From the documentation:
Runs the specified action on the UI thread. If the current thread is the UI thread, then the action is executed immediately. If the current thread is not the UI thread, the action is posted to the event queue of the UI thread.
http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)
Multi Threaded Programming: Theory vs Actual
Puppy Photos Explain is the Best pic.twitter.com/adFy17MTTI— Cian Ó Maidín (#Cianomaidin) 6. april 2015
But joke aside.
If you want to test how the threads work in correlation, try:
runOnUiThread(
new Runnable() {
#Override
public void run() {
updating = false;
updateOptionList();
scrollToLastTapped();
Thread.sleep(100);
Log.d("UI","Updating");
}
});
I'm new to android, I need to start a Thread Multiple times to do a regular work as the listen a thing. But I searched and found that can't do this. So I decided to put
while(true){
listen some thing
do another something depends for listen
}
in the run() method.
But How can I implements this idea? Is it possible ? and How?
You should use Handler.post() whenever you want to do operations in the UI thread.
So let's say in the callback (which is running in separate thread) you want to change a TextView's text, you should use Handler.post(). In Android, as in many other UI frameworks, UI elements (widgets) can be only modified from main thread.
mHandler = new Handler();
new Thread(new Runnable(
#Override
public void run () {
// Perform long-running task here
// (like audio buffering).
// you may want to update some progress
// bar every second, so use handler:
mHandler.post(new Runnable() {
#Override
public void run () {
// make operation on UI - on example
// on progress bar.
}
});
}
)).start();
Of course, if the task you want to perform is really long and there is a risk user might switch to some another app in the meantime, you should consider using Service.
If you start your thread inside a while loop with true condition, it'll kill your device. You'r device will hang. Your code should be event triggered. You can have a Service running in the background to do that and listen for your events.
I have a Thread with open socket connection in a activity, I like to use the thread globaly so that I can get data from thread in other Activities. Somethink like running on the background...
Does anyone have a solution or examples for me?
Thank u.
You are looking for Service
or try this code
void runInBackground() {
new Thread(new Runnable() {
#Override
public void run() {
// DO your work here
// get the data
if (activity_is_not_in_background) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//uddate UI
}
});
}
runInBackground();
}
});
}
And the third method using Async Task-- Understanding AsyncTask
If you want multiple activities to have access to this thread then I would combine Vaibs_cool's sample of running a thread (it's just a normal Thread, nothing Android specific about it) and then...
extend Application (make an entry for it in the Manifest) and put that Thread in there.
That way all your activities can talk to it.
You have two options:
Service
AsyncTask
If you want to open socket and make it opened even after Activity close use Service
On other hand if you want to open socket during Activity is running and close on Activity close then use AsyncTask
You can find example how to use AsyncTask here
From Docs:
Network operations can involve unpredictable delays. To prevent this from causing a poor user experience, always perform network operations on a separate thread from the UI. The AsyncTask class provides one of the simplest ways to fire off a new task from the UI thread.
My question Is that What is the difference between Thread and Handler
Q1) What are their effects When they are used in 1) Activity 2) Service
Q2) What is difference between them in context with their life span
I am using following codes for them.
1) ---------------------------
final Handler handler = new Handler();
Runnable runnable = new Runnable()
{
public void run()
{
// do somthing
handler.postDelayed(this, 1000);
}
};
runnable.run();
2) ---------------------------
handler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
}
};
new Thread(new Runnable()
{
public void run()
{
while(true)
{
try
{
Thread.sleep(1000);
handler.sendEmptyMessage(0);
} catch (InterruptedException e) {}
}
}
}).start();
Handler:
handler is used to do looper thing.that is to perform same task number of time.
handler can be executed on main thread.
about Handler if its used in service it may get stop if phone state change to sleep.
u can update the UI through handler if it used in activity.
Thread:
Thread is used to things on separate than the main thread of an activity.
thread always runs in background even if phone state changes to sleep mode.
u cant update the UI of as its not running on main thread.it can be done using asynctask not using simple java thread.
Q0) What is the difference between a thread and a handler?
A Thread is the same as it always is in programming. Each thread executes a single call to a method and then terminates. Each thread runs in parallel with every other thread. Threads are in short the way you have more than one thing happening at once.
Passing information between threads is notoriously difficult...
A Handler is Android's way of passing a message from one thread to another. Specifically it allows you to pass a set of instructions as a Runnable into a thread for that thread to execute. Typically they are used as a way for a thread to report its result back to the main thread when it's complete.
Q1) What are their effects When they are used in 1) Activity 2) Service
There is no difference between the way these two items behave in a service or an activity in general except that a service can exist in its own process if android is instructed to do so. Threads in different processes can not directly talk to one another. Services are there to share data,functionality and in some cases threads between activities. There is no requirement for them to have their own thread.
The one major point to note is that only the main thread can update the UI (activity).
Also networking specifically can not be done on the main thread. Networking is usually done from within a service so that the results can be shared but this is not necessary.
The limitations around what must and must not be done in the main thread make threading a little tricky, but these limitations are there to help you avoid freezing the UI unexpectedly.
Q2) What is difference between them in context with their life span I am using following codes for them.
Difficult to answer as I don't understand the purpose of your code.
As an example. Android no longer allows you to do any networking on the main thread as this could freeze the UI while it's waiting for the server to respond over a poor wifi connection. To change something on the UI based on something retrieved from the network you must use a thread to do the networking and pass the data back to the main thread to update the UI.
A (doctored) snippet from my code looks like this:
private final Handler handler = new Handler();
#Override
protected void onCreate( Bundle savedInstanceState ) {
// irreverent to the example
super.onCreate(savedInstanceState);
super.setContentView(R.layout.abstract_main_view);
// Here's the example
Thread networkThread = new Thread() {
#Override
public void run() {
// This could take several seconds
final Collection<Player> players = service.lookupAllPlayers();
Runnable uiUpdate = new Runnable() {
#Override
public void run() {
// This is quick, just adding some text on the screen
showPlayers(players);
}
};
handler.post(uiUpdate);
}
};
networkThread.start();
}
In this example:
The handler is created and exists for the duration of this activity. Because this class is constructed by the main thread, the Handler is also. This means that all messages posted to this handler will be executed by main.
networkThread is created and started by the main thread in onCreate. This lives until it has retrieved the data from the network and posted a response back to the main thread. Then it's done.
The Runnable uiUpdate is created by networkThread once all data is retrieved. It does not have a thread associated and so does not execute right away. Instead it is posted back to main using the handler. It is then executed on the main thread and discarded once complete.
One can use a Handler to inform one thread of events from another thread.
Typical usage would be to inform the UI Thread from other threads.
We can not modify UI elements from other threads directly. So we can define a Handler as a member of an Activity instead.
Activities are created on the UI Thread so this handler also is on UI Thread.
So then from another thread we send a message to the Handler. And on receiving the message the Handler modifies some UI elements.