Can't create handler inside thread that has not called Looper.prepare()
You're calling it from a worker thread. You need to call Toast.makeText()
(and most other functions dealing with the UI) from within the main thread. You could use a handler, for example.
Look up Communicating with the UI Thread in the documentation. In a nutshell:
// Set this up in the UI thread.
mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message message) {
// This is where you do your work in the UI thread.
// Your worker tells you in the message what to do.
}
};
void workerThread() {
// And this is how you call it from the worker thread:
Message message = mHandler.obtainMessage(command, parameter);
message.sendToTarget();
}
Other options:
You could use Activity.runOnUiThread()
. Straightforward if you have an Activity
:
@WorkerThread
void workerThread() {
myActivity.runOnUiThread(() -> {
// This is where your UI code goes.
}
}
You could also post to the main looper. This works great if all you have is a Context
.
@WorkerThread
void workerThread() {
ContextCompat.getMainExecutor(context).execute(() -> {
// This is where your UI code goes.
}
}
Deprecated:
You could use an AsyncTask, that works well for most things running in the background. It has hooks that you can call to indicate the progress, and when it's done.
It's convenient, but can leak contexts if not used correctly. It's been officially deprecated, and you shouldn't use it anymore.
Can't create handler inside thread that has not called Looper.prepare() - Google Translate
You don't need to create a new Handler. You can use any view as a Handler.
txtSource.post(new Runnable() {
public void run(){
txtSource.setText(...
}
});
If you really want to create a Handler, then as mentioned in the error message, call Looper.prepare();
in the first line of doInBackground
and Looper.loop()
in the last line.
doInBackground(){
Looper.prepare();
//your code
Lopper.loop();
}
If your code is inside an activity or have the reference of activity, you can directly do stuffs in the UI thread using the method runOnUiThread
Can't create handler inside thread which has not called Looper.prepare()
The error is self-explanatory... doInBackground()
runs on a background thread which, since it is not intended to loop, is not connected to a Looper
.
You most likely don't want to directly instantiate a Handler at all... whatever data your doInBackground()
implementation returns will be passed to onPostExecute()
which runs on the UI thread.
mActivity = ThisActivity.this;
mActivity.runOnUiThread(new Runnable() {
public void run() {
new asyncCreateText().execute();
}
});
ADDED FOLLOWING THE STACKTRACE APPEARING IN QUESTION:
Looks like you're trying to start an AsyncTask
from a GL rendering thread... don't do that cos they won't ever Looper.loop()
either. AsyncTasks are really designed to be run from the UI thread only.
The least disruptive fix would probably be to call Activity.runOnUiThread()
with a Runnable
that kicks off your AsyncTask
.
how to fix Can't create handler inside thread that has not called Looper.prepare()
Call looper.prepare()
in the run()
method of your new thread.
A Handler
can't dispatch Messages
or Runnables
to the Looper
of a thread if it does not exist. Refer to this in the official documentation.
Can't toast on a thread that has not called Looper.prepare()
You CANNOT show a Toast
on non-UI thread. You need to call Toast.makeText()
(and most other functions dealing with the UI) from within the main thread.
You could use Activity#runOnUiThread():
runOnUiThread(new Runnable() {
public void run() {
final Toast toast = Toast.makeText(context, "GAME OVER!\nScore: " + score, duration);
toast.show();
}
});
If you want execute a instrumentation test on main thread, add @UiThreadTest
annotation:
@Test
@UiThreadTest
public void useAppContext() {
// ...
}
P.s: There are also many other ways with explain (using Handler, Looper, Observable..) in these posts: Android: Toast in a thread and Can't create handler inside thread that has not called Looper.prepare()
Can't create handler inside thread Thread[Thread-5,5,main] that has not called Looper.prepare()
Inside your onResponse
show your dialog like below inside a UI thread
activity.runOnUiThread(new Runnable() {
public void run() {
new AlertDialog.Builder(mcontext)
.setTitle("title:")
.setMessage(TmpPwd)
.setPositiveButton("close", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.show();
}
});
Related Topics
How to Add a Badge to an Application Icon in Android
Listview with Clickable/Editable Widget
How to Get String from Different Locales in Android
Android Studio Gradle Configuration with Name 'Default' Not Found
How to Start an Activity from a Service
How to Save Geofire Coordinates Along with Other Items in Firebase Database
How to Get the Sender of an Intent
How to Create and Read Log on Android Devices
Android Log.V(), Log.D(), Log.I(), Log.W(), Log.E() - When to Use Each One
How to View Androidmanifest.Xml from APK File
Adb Not Responding - Wait More or Kill Adb or Restart (Ubuntu 13) 64-Bit
Difficulties with Calling an Android Ndk Function from Directly Delphi
Do X86 Android Avd's Work on Linux on Amd
How to Change Endianness Mid-Execution on Arm (Android/Linux)