Exception while Starting an Activity from TimerTask - android

I'm trying to start a an activity only after some data is ready in the Service
I'm trying this with a timer task which constantly polls the service for the data readness
public class SplashTask extends TimerTask {
#Override
public void run() {
Log.i(MY_DEBUG_TAG, "Internet is accessible, Running some Spalsh screen Tasks ");
if(mBoundService.isDataReady()) {
Log.e(MY_DEBUG_TAG, "Data is ready in service..");
startActivityForResult(new Intent(SplashDroid.this, FunWithDataActivity.class), 3);
} else {
Log.e(MY_DEBUG_TAG, "Data not ready in service..");
}
Log.i(MY_DEBUG_TAG, "Spalsh Tasks fnished..");
}
}
Issue is that when data is ready and FunWithDataActivity about to start, i'm getting the following error
07-27 14:53:40.614: ERROR/AndroidRuntime(1042): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

startActivityForResult has to be called from the UI thread (which is not the thread in which the handler executes). To achieve this, move the startActivityForResult code to a Runnable and run it using runOnUiThread inside the run().

You can't use startActivityForResult from non-UI thread. You can either use runOnUiThread() or Handler.post().
Also, you shouldn't really use separate thread for polling. Use Handler's postDelayed() function for polling. This way you won't wasted whole thread for simple polling. For an example see: Repeat a task with a time delay?

Try to use the CountDownTimer class instead. You can also see this answer for an example: TimerTask in Android?

Worth looking into these post:
Can't create handler inside thread that has not called Looper.prepare()
Can't create handler inside thread that has not called Looper.prepare() inside AsyncTask for ProgressDialog
If not resolved,Could u post your code where u r facing the problem!!

Related

Android background task

I need to start background task. Task call async http request and if condition is valid show alert.
I implemented it but I receive this error:
java.lang.RuntimeException:
Can't create handler inside thread that has not called
Looper.prepare()
This is my java code:
Timer timer = new Timer();
timer.schedule(new RequestScheduledTask(), intervalTask);
class RequestScheduledTask extends TimerTask {
#Override
public void run() {
myCall();
}
}
Can you help me please?
Thanks
Luca
for example I need refresh adapter list when data is changed. Data returned from webserver could to be changed or not. if it is changed I must refresh listview/adapter, else nothing.
myCall call server, get data response (using other framwork like volley) and then update list view.
When myCall start I want display loading indicator but when I show it, app crash with runtime exception
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
According to the following post you are doing something in a thread that is meant to be called on the main thread! What is myCall(); doing?
Can't create handler inside thread that has not called Looper.prepare()
And don't do http request with async tasks thats bad practice.
I would recomment to use volley:
http://www.itsalif.info/content/android-volley-tutorial-http-get-post-put
[edit]
Okay its the loading indicator that is should be called on the main thread. I guess you are doing it in the AsyncTask.
You can use Activity.runOnUiThread(Runnable()) to run a runnable to display it.

Understanding what Looper is about in Android

I had to add Looper to the following code:
public class MyRunnable implements Runnable
{
#Override
public void run()
{
Looper.prepare();
final Looper looper = Looper.myLooper();
new Handler().postDelayed(
new Runnable()
{
#Override
public void run()
{
try
{
}
catch (Exception ex)
{
}
finally
{
looper.quit();
}
}
}, 100);
Looper.loop();
}
}
Notice that I have a runnable inside a runnable. The nested runnable gets executed through a Handler. Initially I didn't have Looper but Android complained that I needed to call Looper.prepare before executing another thread.
I read up on Looper but it still seems kind of cryptic. It seems to act like some kind of internal messaging pipeline. It isn't clear to me why this is necessary since there are no messages going from my outer runnable to my inner runnable. Even though that is true, it seems that Android just makes the hard rule that if you call a thread from a thread, you MUST also call Looper.prepare. Even if I accept that as-is, it still doesn't help to understand why I need to call looper.loop and looper.quit. If I omit Looper.loop, my Handler never runs and that is what isn't clear. What does Looper.loop do that allows my Handler to run?
Here is a great article about that.
Looper and Handler in Android
It comes along with a simple schema that leads to straight understanding of relationship between Loopers and Handler.
On this schema, we see that, within the same thread (depicted by the big rectangle), no matter how many handler you create, they will all be using the same Looper, i.e., the unique looper of this thread.
Note:
Looper have to be prepared to allow associated handler to process posted messages.
Android application, more precisely, android app UI thread(the main thread), already comes with a prepared looper (the mainLooper).
Here is how to Communicating with the UI Thread.
A simple concept of the looper:
Every worker thread you create and run ends once it performs its last operation.
To prevent your thread termination you can start a loop by calling Looper.loop(), think of it as while(true){} statement. Before calling Looper.loop() you have to prepare the loop with Looper.prepare(), if it is not prepared yet.
To terminate the loop and end your thread you will need to call looper.quit() on the looper.
Now for the notification you got from Android:
When you create a Handler in a thread, it will be bound to the thread it is created in and when you post runnable using this Handler, the code runs on the thread of the Handler.
So when the system saw that you want to run some code (especially 100ms in future) on a Handler that is bound to a thread that is going to die as soon as it finishes calling the post method it proposed to use Looper.loop() to prevent this thread from terminating and thus enabling you properly run the second Runnable in a still existing thread.
I find the following tutorial very helpful in understanding the concept of looper .
Intro to looper and handler

How to run an infinite loop in Android without freezing the UI?

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();
}

MapView and AsyncTask

I am trying to use an AsyncTask class that I created to update a MapView. The problem is I am getting this error when I make my call to execute the AsyncTask:
"Can't create a Handler inside a thread that has not called Looper.prepare()"
I have tried running the Task on the UI Thread using
Handler hand = new Handler(Looper.getMainLooper());
hand.post(new Runnable() {
public void run() {
new RxThread().execute();
}
});
But that just gives me the same error. I realize that my MapView doesn't call looper prepare, and that I'm having troubles getting this to work since I'm running the MapView on a seperate activity rather than the Main Activity. Does anyone have a good solution to this?
IIRC, your error is because you are first referencing AsyncTask on a background thread. You can only create and execute() an AsyncTask on the main application thread.

Handler or runOnUiThread solution for "Can't create handler inside thread that has not called Looper.prepare() "

Recently, I show up a toast in user thread and got the above runtime error.
From Can't create handler inside thread that has not called Looper.prepare(), they proposed use Handler as solution. However, I saw the solution is quite lengthy and cumbersome.
My own solution is to use runOnUiThread
private void showTooDarkToastMessage()
{
((Activity) this.getContext()).runOnUiThread(new Runnable() {
#Override
public void run() {
Toast toast = Toast.makeText(getContext(), getResources().getString(R.string.toast_toodark), Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
});
}
I was wondering, is there any shortcoming of using runOnUiThread, compared to Handler?
Because you are showing a UI element (a Toast message) runOnUiThread is perfect.
A Handler will run its task on the specified thread. For instance,
protected void onCreate( Bundle savedInstanceState )
{
Handler hander = new Handler();
//Create thread, post to handler
}
would create a new Handler that would run its posts on the UI thread. calling Activiy.runOnUiThread just posts the runnable specifically to the UI thread. By default, Handlers will run on whatever thread they were created in. The above code would work identical to using runOnUiThread because the onCreate method is run on the UI thread!
Handlers would be preferred if you needed to communicate between multiple background threads.
Because mobile devices have limited resources, work run on the UI thread should be kept relatively light. Intense work done on the UI thread can cause Application Not Responding (ANR) errors and can cause the OS to kill your process.
Actually runOnUiThread() using Handler inside. So, there is no downsides to use runOnUiThread() if you want to simple post some job to do in the UI Thread.
If you are interesting in difference between Handler and runOnUiThread() you can read about it in this answer

Categories

Resources