Hi I am trying to execute the code below it suppose to open a loading dialog and dismiss it in the if statement.
here is the code:
loginBtn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View view)
{
final ProgressDialog progress = ProgressDialog.show(thisActivity, "Please wait", "Loading please wait..", true);
Thread loginThread = new Thread(new Runnable()
{
#Override
public void run()
{
try
{
boolean userAllowed = login.loginUser(userEmail.getText().toString(), userPass.getText().toString());
if(userAllowed)
{
progress.dismiss();
startActivity(mainPage);
}
else
{
progress.dismiss();
Toast.makeText(context, "Invalide email and password", Toast.LENGTH_LONG).show();
}
}
catch (Exception e)
{
Toast.makeText(context, "There is some problem", Toast.LENGTH_LONG).show();
}
}
});
loginThread.start();
}
});
the logCat error output is:
05-09 22:37:26.508: E/AndroidRuntime(24820): FATAL EXCEPTION: Thread-1306
05-09 22:37:26.508: E/AndroidRuntime(24820): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
05-09 22:37:26.508: E/AndroidRuntime(24820): at android.os.Handler.<init>(Handler.java:197)
05-09 22:37:26.508: E/AndroidRuntime(24820): at android.os.Handler.<init>(Handler.java:111)
05-09 22:37:26.508: E/AndroidRuntime(24820): at android.widget.Toast$TN.<init>(Toast.java:324)
05-09 22:37:26.508: E/AndroidRuntime(24820): at android.widget.Toast.<init>(Toast.java:91)
05-09 22:37:26.508: E/AndroidRuntime(24820): at android.widget.Toast.makeText(Toast.java:238)
05-09 22:37:26.508: E/AndroidRuntime(24820): at com.shale.activities.MainActivity$1$1.run(MainActivity.java:93)
05-09 22:37:26.508: E/AndroidRuntime(24820): at java.lang.Thread.run(Thread.java:856)
My reference was this tutorial.
Thanks!
as in Log :
RuntimeException: Can't create handler inside thread that has not
called Looper.prepare()
means you are trying to update or access UI elements from non ui Thread . so you will need to use Activity.runOnUiThread , Handler or AsyncTask for updating or accessing UI from other Thread. do it as:
Your_Activity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
//update Ui elements here
}
});
You can't do anything UI related (including dismissing dialogs) unless you're on the UI thread. You need to offload that via a runOnUiThread or by passing a message to a handler on the UI thread. Or better yet- make that thread an AsyncTask and do it in the onPostExecute()
An alternative to the above would be to send a broadcast and have a BroadcastReceiver handle receiving that broadcast and act upon it as you wish.
Related
Not able to set the data in the database in server...getting values from editText and passing them in doBackground() but error occured while executing in background...any help will be appreciated...thanx in advance...log added......
Here is the log
9 10:27:05.333 3245-3523/com.amar.schooladmin E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #7
Process: com.amar.schooladmin, PID: 3245
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.widget.Toast$TN.<init>(Toast.java:703)
at android.widget.Toast.<init>(Toast.java:145)
at android.widget.Toast.makeText(Toast.java:458)
at com.amar.schooladmin.AddRecord$CreateNewProduct.doInBackground(AddRecord.java:77)
at com.amar.schooladmin.AddRecord$CreateNewProduct.doInBackground(AddRecord.java:61)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
01-19 10:27:0
MainActivity.java
button7.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new CreateNewProduct().execute();
roll=editText.getText().toString();
name=editText2.getText().toString();
address=editText3.getText().toString();
fname=editText4.getText().toString();
mname=editText5.getText().toString();
}
});
}
public class CreateNewProduct extends AsyncTask<String, String, String>
{
#Override
protected String doInBackground(String... strings) {
List<NameValuePair> parms = new ArrayList<>();
parms.add(new BasicNameValuePair("roll", roll));
parms.add(new BasicNameValuePair("name", name));
parms.add(new BasicNameValuePair("address", address));
parms.add(new BasicNameValuePair("fname", fname));
parms.add(new BasicNameValuePair("mname", mname));
JSONObject jsonObject = jsonParser.makeHttpRequest(url, "POST", parms);
try {
int success= jsonObject.getInt("TAG SUCCESSFULLY");
} catch (Exception e) {
Toast.makeText(AddRecord.this, ""+e.toString(), Toast.LENGTH_SHORT).show();
}
return null;
}
The problem is you are showing Toast in doInBackground(). try this
((Activity) context).runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(AddRecord.this, ""+e.toString(), Toast.LENGTH_SHORT).show();
}
});
You can't write show() method of Toast in doInBackground() because it is not UI thread it is worker thread. You can write Toast in onPostExecute().
Toast is causing the crash to occur, because Toast requires UI Thead to display and currently it is in background thread.
Also, you are getting exception at
int success= jsonObject.getInt("TAG SUCCESSFULLY");
and hence in catch Toast line is getting executed.
Please check if TAG SUCCESSFULLY key exists in jsonObject or not. Use
if(jsonObject.has("TAG SUCCESSFULLY"))
success= jsonObject.getInt("TAG SUCCESSFULLY");
i m new in android and trying to make simple program that can print variable in AsyncTask Class
here is my code
int a,b,c;
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
a =10;
b=10;
c=a+b;
Context ctx = null;
show(c, ctx );
return null;
}
public void show(int c2 ,Context c) {
// TODO Auto-generated method stub
Toast.makeText(c, "AsyncTask classs + c2 ", Toast.LENGTH_SHORT).show();
}
after running this program , i m getting run time Error
here us LogCat file view
Process: com.example.asycclass, PID: 2539
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.widget.Toast$TN.<init>(Toast.java:327)
at android.widget.Toast.<init>(Toast.java:92)
at android.widget.Toast.makeText(Toast.java:241)
at com.example.asycclass.MainActivity$AttemptLogin.show(MainActivity.java:74)
at com.example.asycclass.MainActivity$AttemptLogin.doInBackground(MainActivity.java:65)
at com.example.asycclass.MainActivity$AttemptLogin.doInBackground(MainActivity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
Move your show Toast code inside runOnUiThread like :
runOnUiThread(new Runnable() {
#Override
public void run() {
show(c, ctx );
}
});
I guess that the problem is that you're trying to create a Toast not from the main thread.
You must create a handler and Runnable for that and use handler.post()
For example
Runnable showToast = new Runnable() {
public void run() {
// Create your Toast here or whatever you want
}
}
Hi I am trying to use the service class for first time and have been facing problems. What I want is an infinitely running (unless killed by Android System) service with an active Network connection. I have written the code which works fine on Android 4.3 and 4.4 but the application crashes when I try running on Android 2.2. My code is as follows:
public class BackgroundMusicService extends Service {
private MediaPlayer mp;
private int id;
private static class BackgroundAsyncTaskClass extends AsyncTask<Void, Void, Void>{
protected Void doInBackground(Void... params) {
Log.v("Async","Async Called");
/*Network connection will be created here*/
return null;
}
}
private class ForThread implements Runnable{
public void run() {
while (true) {
try {
Log.v("ThreadSleeping","5 sec");
BackgroundAsyncTaskClass task = new BackgroundAsyncTaskClass();
task.execute();
Thread.sleep(5000);
} catch (InterruptedException e) {
}finally{
Log.v("Finally called","Finally called");
}
}
}
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v("onStartCommand Called","onStart Command Called");
Thread t;
ForThread ft = new ForThread();
t = new Thread(ft);
t.start();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
if(null != mp){
mp.stop();
mp.release();
Log.v("Destroyed","onDestroy Called");
}
}
public void onTaskRemoved(Intent rootIntent) {
Intent restartServiceIntent = new Intent(getApplicationContext(),
this.getClass());
restartServiceIntent.setPackage(getPackageName());
PendingIntent restartServicePendingIntent = PendingIntent.getService(
getApplicationContext(), 1, restartServiceIntent,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext()
.getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 1000,
restartServicePendingIntent);
super.onTaskRemoved(rootIntent);
}
}
and the exception thrown by Android 2.2 is as follows:
04-28 09:51:41.435: W/dalvikvm(280): threadid=7: thread exiting with uncaught exception (group=0x4001d800)
04-28 09:51:41.435: E/AndroidRuntime(280): FATAL EXCEPTION: Thread-8
04-28 09:51:41.435: E/AndroidRuntime(280): java.lang.ExceptionInInitializerError
04-28 09:51:41.435: E/AndroidRuntime(280): at com.example.backgroundservicedemo.BackgroundMusicService$ForThread.run(BackgroundMusicService.java:45)
04-28 09:51:41.435: E/AndroidRuntime(280): at java.lang.Thread.run(Thread.java:1096)
04-28 09:51:41.435: E/AndroidRuntime(280): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
04-28 09:51:41.435: E/AndroidRuntime(280): at android.os.Handler.<init>(Handler.java:121)
04-28 09:51:41.435: E/AndroidRuntime(280): at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
04-28 09:51:41.435: E/AndroidRuntime(280): at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
04-28 09:51:41.435: E/AndroidRuntime(280): at android.os.AsyncTask.<clinit>(AsyncTask.java:152)
Also, when I try using handler.post(new Runnable(){.... run(){}....} The UI hangs up but the background thread continues running and exits after it becomes out of memory.
Another thing that I have doubts about is:
When the application restarts, I want this active Service to stop, but how do I get a reference to this thread running in Background and how do I stop this? I would appreciate if anyone can redirect me to a suitable link/reference or could help me out with the code. Thanks
You have this inside a thread's run method
BackgroundAsyncTaskClass task = new BackgroundAsyncTaskClass();
task.execute();
Threading rules from the docs
The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
The task instance must be created on the UI thread.
execute(Params...) must be invoked on the UI thread.
Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
This question already has answers here:
Can't create handler inside thread that has not called Looper.prepare()
(30 answers)
Threading - Can't create handler inside thread that has not called Looper.prepare()
(1 answer)
Closed 9 years ago.
I get the following error:
08-27 17:49:17.995: E/AndroidRuntime(10085): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
08-27 17:49:17.995: E/AndroidRuntime(10085): at android.os.Handler.<init>(Handler.java:121)
08-27 17:49:17.995: E/AndroidRuntime(10085): at android.widget.Toast$TN.<init>(Toast.java:361)
08-27 17:49:17.995: E/AndroidRuntime(10085): at android.widget.Toast.<init>(Toast.java:97)
08-27 17:49:17.995: E/AndroidRuntime(10085): at android.widget.Toast.makeText(Toast.java:254)
when running the first line of:
public static void alertUser(String str) {
Toast toast = Toast.makeText(mInstance.getApplicationContext(), str,
Toast.LENGTH_LONG);
toast.show();
}
how can i fix this?
Something like this should work:
public static void alertUser(String str) {
runOnUiThread(setErrorMessage);
}
private Runnable setErrorMessage = new Runnable() {
#Override
public void run() {
Toast toast = Toast.makeText(mInstance.getApplicationContext(), str,
Toast.LENGTH_LONG);
toast.show();
}
};
I am having problems executing a AlertDialog on a postexecute(). Throws this exception
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Alternatively, when I placed the AlertDialog.Builder in, it just didn't work
Pls help.
Also in a case were a wrong password is entered, the process is terminated. How can I call a Toast method in a case were the usename or password is invalid
Below is the code snippet
public void Login() {
// Toast.makeText(getBaseContext(), pass.getText() + " "
// +user.getText(),
// Toast.LENGTH_SHORT).show();
String url = "http://107.20.195.151/mcast_ws/" + "?user="
+ user.getText().toString() + "&password="
+ pass.getText().toString();
result = getHttpResponse(url);
}
String result;
private String getHttpResponse(String location) {
result = "";
URL url = null;
Log.d(LOGTAG, " " + "location " + location);
try {
url = new URL(location);
} catch (MalformedURLException e) {
Log.e(LOGTAG, " " + "error" + e.getMessage());
}
if (url != null) {
try {
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String inputLine;
int lineCount = 0;
while ((inputLine = in.readLine()) != null) {
result += inputLine.trim();
}
in.close();
connection.disconnect();
} catch (Exception e) {
Log.e(LOGTAG, " " + "IOError " + e.getMessage());
Toast.makeText(getBaseContext(), "No Internet Access",
Toast.LENGTH_SHORT);
}
} else {
Log.e(LOGTAG, " " + "url" + url);
}
return result;
}
class PostToTwitter extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
Login();
Log.d(LOGTAG, "Success");
Log.d(LOGTAG, result);
Log.d(LOGTAG, result.substring(0, 16).trim());
// Log.d(TweetActivity.getLogtag(),"Successfully Posted: " +
// params[0]);
return "success";
}
#Override
protected void onPostExecute(String r) {
// TODO Auto-generated method stub
super.onPostExecute(result);
String msg = "Login successful";
if (result.substring(0, 16).trim().equals(msg)) {
// System.out.println(result.substring(0, 16).trim());
Log.d(LOGTAG, " " + "Connection Test" + result);
AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
builder.setMessage("Are you sure send this SMS?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//...Attach another thread event to send the sms
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
Log.e(LOGTAG, "Error detected 2");
AlertDialog alert = builder.create();
alert.show();
//return "success";
// Toast.makeText(getBaseContext(),
// "Login Succesful",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getBaseContext(),
"Login UnSuccesful. Check Username or password",
Toast.LENGTH_SHORT).show();
//return null;
}
// Toast.makeText(getApplicationContext(), result
// ,Toast.LENGTH_SHORT).show();
Log.e(LOGTAG, "Error detected");
/*
Intent i = new Intent("com.sms.subsahara.COMPOSESMS");
startActivity(i);
//Log.e(LOGTAG, " " + "error2");*/
}
}
On applying the suggestions from Alex, I modified the original code this above, but still get an error.Below is the exception from the logcat
E/AndroidRuntime( 326): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime( 326): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
E/AndroidRuntime( 326): at android.view.ViewRoot.setView(ViewRoot.java:472)
E/AndroidRuntime( 326): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
E/AndroidRuntime( 326): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
E/AndroidRuntime( 326): at android.app.Dialog.show(Dialog.java:239)
E/AndroidRuntime( 326): at com.sms.subsahara.WebMessengerActivity$PostToTwitter.onPostExecute(WebMessengerActivity.java:216)
E/AndroidRuntime( 326): at com.sms.subsahara.WebMessengerActivity$PostToTwitter.onPostExecute(WebMessengerActivity.java:1)
E/AndroidRuntime( 326): at android.os.AsyncTask.finish(AsyncTask.java:417)
E/AndroidRuntime( 326): at android.os.AsyncTask.access$300(AsyncTask.java:127)
E/AndroidRuntime( 326): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
E/AndroidRuntime( 326): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 326): at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 326): at android.app.ActivityThread.main(ActivityThread.java:4363)
E/AndroidRuntime( 326): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 326): at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 326): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
E/AndroidRuntime( 326): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
E/AndroidRuntime( 326): at dalvik.system.NativeStart.main(Native Method)
doInBackground is not synchronized with the UI thread, which means you cannot directly manipulate UI elements, launch dialogs, etc. from within the method. The fix is easy. Simply move your AlertDialog code to the onPostExecute method (which is synchronized with the UI thread).
When working with AsyncTasks, remember that:
doInBackground is meant to perform the potentially expensive operation (network access, socket connection, database query, etc.)
onPostExecute is meant to do something with the results, if you wish (this method is synchronized with UI thread, so you can manipulate UI elements directly)
DoInBackground() only gets executed on a different thread than the main UI thread. That is the whole point of the AsyncTask.
There are 3 ways to post your results to the UI (pretty much... to the UI Thread)
use onPostExecute method. You get the return value of your doInBackground method passed in, and you can do anything with it. (I think this matches your use case.)
If your task is on going, and you want little bursts of information on the UI, like a progress bar update, use publishProgress(...) from doInBackground method, which will then be passed in to your onProgressUpdate(...) method in AsyncTask, which will run on the UI Thread.
Similar to 2, but you can use RunOnUiThread(...) convenience method to throw a runnable to run in the UI Thread. May not be the prettiest code when you have multiple anonymous methods floating around, but it's for quick and dirty way to do it. NOTE that this method is available on the Activity Class, and not Context class, which may be a deal breaker for some scenarios.
I guess it's because you Login () is in AsyncTask inside the execution, not in the mainUI inside execution. Can onPostExecute handler out in inside, back to the main thread execution; Also can use in onPostExecute UIThread:
runOnUiThread(new Runnable() {
#Override
public void run() {
Login();
}
});
I hope it can help you.
#Alex Lockwood
AsyncTask.doInBackground(Void..params) is ill suited for very long and repetitive operations, the better replacement would be a HandlerThread.
Reason:
In android 3.2, AsyncTask changed its implementation in a significant way. Starting in Android 3.2, AsyncTask does not create a thread for each instance in AsyncTask, instead it uses an executor to run background work work for all AsyncTasks on a single background thread! That means that each AsyncTask thread must run one after another. So, for example, if you have a long AsyncTask thread (image fetcher from a REST), I suggest using a HandlerThread instead, because the long task running thread could probably delay the whole chain.
BUT
It is possible to safely run AsyncTask in parallel by using a thread pool executor instead, but I don't know the exact reason, programmers don't recommend doing so, there are couple of reasons behind that which is not relevant to this post. But in case you do this, I would suggest you do your own threading instead, using handlers to communicate to the main thread when necessary.