Below is an async class i created that i am trying to implement a dialog on execute and a Toast on complete.
How ever no toast or dialog are ever showing up.
my asykTask:
public class EmailPictureService extends HTTPRequestAsyncTask {
Context context;
ProgressDialog dialog;
public EmailPictureService(Context context){
this.context = context;
//dialog = new ProgressDialog(context);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(Object... params) {
Log.v("Start EMAIL SERVICE","START YOPPPPPPPPPPPPPPPPPPPPPP!");
dialog = new ProgressDialog(context);
dialog.setMessage("Sending...");
dialog.setIndeterminate(true);
dialog.show();
HTTPInvoker invoker = new HTTPInvoker();
HttpResponse response = null;
EmailPicture emailPicture = new EmailPicture();
emailPicture.setDeviceType("TABLET");
emailPicture.setStoreId((String)params[1]);
emailPicture.setNotificationType("E");
emailPicture.setRecipientName((String)params[2]);
emailPicture.setRecipientEmail((String)params[3]);
String jsonString = JSONConverter.toJson(emailPicture);
response = invoker.invokePOSTFileService((String)params[0], jsonString, (File[])params[4]);
return parseHttpResponse(response);
}
#Override
protected void onPostExecute(String result) {
String msg = "";
if (dialog.isShowing()) {
dialog.dismiss();
}
if (result != null) {
JSONObject jsonObject = null;
long errorCode = 0;
try {
jsonObject = new JSONObject((String) result);
errorCode = jsonObject.getLong("errorCode");
if(errorCode<1){
msg ="Success, your picture has been sent";
}else{
msg = "Sorry, there was an error sending your picture. Please try again later.";
}
Log.i(Constants.TAG, "Error Code...." + errorCode);
Toast toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
toast.show();
} catch (JSONException e1) {
Log.i(Constants.TAG, "Exception...." + e1);
Toast toast = Toast.makeText(context, "Failure: "+e1, Toast.LENGTH_SHORT);
toast.show();
e1.printStackTrace();
}
}
}
}
how i call it from my activity:
new EmailPictureService(this).execute(url,storeID,cusName, cusEmail, new File[]{file});
my log
You should not attempt to access the UI from doInBackground(). The purpose of AsyncTasks and doInBackground() is avoid bogging down the UI thread... Instead you should preform the UI work in the appropriate methods: onPreExecute(), onProgressUpdate(), onPostExecute(), etc
I suspect the toast isn't showing because your result is always null. Your log shows an error on the post
As others have said, start your progress dialog from onPreExecute()
I note that you instantiate your progressDialog in doInBackground(). Move it to onPreExecute() instead. doInBackground() are only supposed to do non-UI work. =)
This should "solve" your problem.
Related
i'm developing an android App.
The user registration process calls a service that sends an email so it takes several seconds, like 5 or 6 seconds,that's why I execute that task within a thread. The problem is, the Dialog is never dismissing. It stays rolling and the user can do nothing. Here's my code:
try
{
final ProgressDialog progDailog = new ProgressDialog(ActividadAltaUsuario.this);
new Thread(new Runnable()
{
#Override
public void run()
{
try
{
URL url = new URL("slowWS");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
InputStream in = new BufferedInputStream(conn.getInputStream());
String response = IOUtils.toString(in, "UTF-8");
final JSONObject jsonPrincipal = new JSONObject(response);
Boolean success = jsonPrincipal.get("status").toString() == "true";
if (success)
{
ActividadAltaUsuario.this.runOnUiThread(new Runnable() {
#Override
public void run() {
progDailog.show(ActividadAltaUsuario.this, "Sendind email");
}
});
final String idUsuario = jsonPrincipal.get("idUsuario").toString();
URL url2 = new URL("anotherSlowWS");
HttpURLConnection conn2 = (HttpURLConnection) url2.openConnection();
conn2.setRequestMethod("POST");
InputStream in2 = new BufferedInputStream(conn2.getInputStream());
String response2 = IOUtils.toString(in2, "UTF-8");
JSONObject jsonRtaMail = new JSONObject(response2);
//finish();
}
else
{
//finish();
showToast(jsonPrincipal.get("message").toString());
}
ActividadAltaUsuario.this.runOnUiThread(new Runnable() {
#Override
public void run() {
progDailog.dismiss();
}
});
}
catch (Exception e)
{
e.printStackTrace();
}
}
}).start();
}
catch(Exception e)
{
Log.e("log_tag", "Error in http connection" + e.toString());
}
Can anybody help me?
Thanks!
AsyncTask would be a better approach instead of thread, Replace your network call from thread to use AsyncTask. You can use something like this
private class LongOperation extends AsyncTask<Void, Void, Void> {
#Override
protected String doInBackground(Void... params) {
//Main stuff that needs to be done in background
}
#Override
protected void onPostExecute(Void result) {
//Post Execution this method will be called, handle result accordingly
//You can dismiss your dialog here
}
#Override
protected void onPreExecute() {
//Do initialization relative stuff here
// Initialize your dialog here.
}
}
As both onPostExecute() and onPreExecute() work on main thread you can show and dismiss your dialog in this methods.
The UI controls have to be accessed only from the UI thread.
Usually I do this in class that extends AsyncTask
Something like:
public class MyTask extends AsyncTask {
protected void onPreExecute() {
//create and display your alert here
progDialog = ProgressDialog.show(MyActivity.this,"Please wait...", "Logging ...", true);
}
protected Void doInBackground(Void... unused) {
// here is the thread's work ( what is on your method run()
...
// if we want to show some progress in UI, then call
publishProgress(item)
}
protected void onProgressUpdate(Item... item) {
// theoretically you can show the progress here
}
protected void onPostExecute(Void unused) {
//dismiss dialog here where the thread has finished his work
progDialog.dismiss();
}
}
LE:
More detalis about AsyncTask https://developer.android.com/reference/android/os/AsyncTask
check especially the Protected Methods
when i run my code, it returns a value as "null"`
private class MessageActivityLoaderTask extends AsyncTask<Void, Void, Contentlist> {
private LinkedMultiValueMap<String, String> formData;
Activity activity;
public MessageActivityLoaderTask(Activity activity) {
this.activity = activity;
}
#Override
protected void onPreExecute() {
formData = new LinkedMultiValueMap<String, String>();
mProgress.setMessage("Please wait..");
mProgress.show();
}
#Override
protected Contentlist doInBackground(Void... params) {
String url = getString(R.string.base_url) + "/example/example1/1";
Contentlist mess = null;
try {
mess = RestUtils.exchangeFormData(url, HttpMethod.GET, formData, Contentlist.class);
} catch (Exception e) {
e.printStackTrace();
mProgress.dismiss();
}
return mess;
}
protected void onPostExecute(Contentlist result) {
if (result== null) {
Toast message = Toast.makeText(ListobjectsActivity.this, "result is empty", Toast.LENGTH_SHORT);
message.show();
} else {
ListactivityAdapter adapter = new ListactivityAdapter(this.activity, result.getContents());
ListView list = (ListView) activity.findViewById(R.id.account);
list.setAdapter(adapter);
mProgress.dismiss();
}
}`
Your AsyncTask looks like it is set up correctly, so onPostExecute() will receive the ContentList returned by doInBackgroun(). Since onPostExecute() is seeing a null, then doInBackground() is returning a null. That means that either doInBackground() is getting an exception and mess is never set to a non-null value by falling through the catch or RestUtils.exchangeFormData() is returning a null.
I suggest that you debug the code in this area to see what is really going on. It is not likely to be an AsyncTask problem.
I am making an app in which I use Asynctack to fetch login details for me
User enters username and password and I the following function from a different class
static int success;
public static boolean authenticate(final String emailId , final String password , final ProgressDialog progressDialog) {
data = new Data();
new AsyncTask<Void , Void, Void>(){
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.setMessage("Authenticating...");
progressDialog.setIndeterminate(false);
progressDialog.setCancelable(true);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... param) {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username" , emailId));
params.add(new BasicNameValuePair("password" , password));
JSONObject json = jsonParser.makeHttpRequest(url_login, "POST", params);
try {
success = json.getInt("success");
if (success ==1){
JSONArray student = json.getJSONArray("student");
JSONObject jobject = student.getJSONObject(0);
...loading details...
}
} catch (JSONException e) {
Log.e("Authentication error" , e.toString());
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
progressDialog.dismiss();
}
}.execute();
if (success==1){
return true;}
else return false;
}
here I call it
ProgressDialog progressDialog = new ProgressDialog(this);
if(Login.authenticate(username,password,progressDialog)) {
Toast.makeText(this, "Authenticated\nWelcome " + Login.data.Fullname, Toast.LENGTH_SHORT).show();
..calling next activity...
...bla bla bla...
}
else Toast.makeText(this, "Authentication Failed" , Toast.LENGTH_SHORT).show();
In this IF condition the ProgressDialog appears and with that 2nd toast appears i.e. Authentication Failed and nothing happens
I think I know whats the problem here but cant figure it out
I think UI thread must wait till the Asynctask completes its task and then return anything
I think UI thread must wait till the AsyncTask completes its task and
then return anything
When calling AsyncTask.execute UI Thread not wait for complete and return from AsyncTask.
But onPostExecute is a method which is called on UI Thread when doInBackground so do all work which want to execute according to AsyncTask result inside onPostExecute method like want to show Toast message or start a new Activity,...
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
progressDialog.dismiss();
if (success==1){
// start new Activity here
}
else {
// show fail message
}
}
You are going in wrong direction. Why make main thread wait when async task is executing?
Instead you can achieve that using following steps
Show ProgressDialog
start async task and let it execute.
in onPostExecute() notify UI to stop the progressDialog
This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 7 years ago.
I am working on an android application which connect with an asp.net web service.. for that when I tested the application is showing response
Android OS on network main thread exception".
My Code
class GetDetails extends AsyncTask<String, String, String>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Loading the result... Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... args)
{
try
{
runOnUiThread(new Runnable() {
#Override
public void run()
{
TextView webserviceResponse = (TextView) findViewById(R.id.textView1);
webserviceResponse.setText("Requesting to server .....");
//Create Webservice class object
WebserviceCall com = new WebserviceCall();
// Initialize variables
String weight = "18000";
String fromUnit = "Grams";
String toUnit = "Kilograms";
//Call Webservice class method and pass values and get response
String aResponse = com.getConvertedWeight("ConvertWeight", weight, fromUnit, toUnit);
//Alert message to show webservice response
Toast.makeText(getApplicationContext(), weight+" Gram= "+aResponse+" Kilograms",
Toast.LENGTH_LONG).show();
Log.i("AndroidExampleOutput", "----"+aResponse);
webserviceResponse.setText("Response : "+aResponse);
}
}
);
}
finally {
}
return null;
}
}
protected void onPostExecute(String file_url) {
// dismiss the dialog once got all details
pDialog.dismiss();
}
}
Move your all code from runOnUiThread(new Runnable() {...} to doInBackground(...)
As runOnUiThread(..) code execute in main thread
also initialized your Views in Activity onCreate(..)
Correct:
class GetDetails extends AsyncTask<String, String, String>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Loading the result... Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... args)
{
try
{
webserviceResponse.setText("Requesting to server .....");
//Create Webservice class object
WebserviceCall com = new WebserviceCall();
// Initialize variables
String weight = "18000";
String fromUnit = "Grams";
String toUnit = "Kilograms";
//Call Webservice class method and pass values and get response
String aResponse = com.getConvertedWeight("ConvertWeight", weight, fromUnit, toUnit);
Log.i("AndroidExampleOutput", "----"+aResponse);
return aResponse;
}
}
return null;
}
}
protected void onPostExecute(String aResponse) {
// dismiss the dialog once got all details
pDialog.dismiss();
//Alert message to show webservice response
Toast.makeText(getApplicationContext(), weight+" Gram= "+aResponse+" Kilograms",
Toast.LENGTH_LONG).show();
webserviceResponse.setText("Response : "+aResponse);
}
}
Hi Use Handler to Update UI.
Handler Example
private Handler handler = new Handler(new Handler.Callback() { #Override public boolean handleMessage(Message msg) {
switch( msg.what ){
case MSG:
progressDialog.show();
break;
case DETACH:
progressDialog.dismiss();
break;
}
return false; } });
Call In Do In Background
Message m=Message.obtain();
prepareMessage(m);
handler.sendMessage(m);
public void prepareMessage(Message m)
{
Bundle b = new Bundle();
b.putString("message", "Activity Done in background!!!!!!!");
m.setData(b);
}
Inside doInBackground() you have written a runonUiThread() method.
And inside that runOnUIThread() you are trying to make network call.That is why it is giving NetworkOnMainThreadException.
Put that network call outside runOnUiThread() String aResponse = com.getConvertedWeight("ConvertWeight", weight, fromUnit, toUnit); but inside doInBackground() I hope it ll work.
Hello
I'm loading Tweets from a user account to show in a listview. Now I want to let the users know what's going on while they're waiting. I've implementend Async Task, but for some reason, onPostExcecute is never called. That's why the dialog is never removed.
Can someone give me a hint.. What am I doing wrong?
I can post my TweetAdapterClass if that's needed
This is my AsyncClass
public class ProgressTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
dialog.setTitle("Even geduld...");
dialog.setMessage("De tweets worden ingeladen...");
dialog.show();
}
protected void onPostExecute() {
try {
if (dialog.isShowing()) {
adaptor = new TweetListAdaptor(MainActivity.this, R.layout.tweetitem, loadTweets());
setListAdapter(adaptor);
dialog.dismiss();
}
} catch (Exception e) {
}
}
#Override
protected Void doInBackground(Void... arg0) {
return null;
}
}
LoadTweets looks like this:
private ArrayList<Tweets> loadTweets() {
ArrayList<Tweets> tweets = new ArrayList<Tweets>();
try {
HttpClient hc = new DefaultHttpClient();
HttpGet get = new HttpGet(
"http://search.twitter.com/search.json?q=JobXXL_be&rpp=10");
// HttpGet get = new
// HttpGet("http://search.twitter.com/search.json?q=Stijn_messiaen&rp=10");
HttpResponse rp = hc.execute(get);
if (rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String result = EntityUtils.toString(rp.getEntity());
JSONObject root = new JSONObject(result);
JSONArray sessions = root.getJSONArray("results");
for (int i = 0; i < sessions.length(); i++) {
JSONObject session = sessions.getJSONObject(i);
Tweets tweet = new Tweets();
tweet.setTweet(session.getString("text"));
tweet.setUser(session.getString("from_user"));
// datum vertalen
String date = session.getString("created_at").substring(5,
16);
String[] arrDate = date.split(" ");
int id = this.getResources().getIdentifier(
arrDate[1].toString(), "string",
this.getPackageName());
String maand = getResources().getString(id);
date = arrDate[0].toString() + " " + maand + " "
+ arrDate[2].toString();
tweet.setDate(date);
tweets.add(tweet);
}
}
} catch (Exception e) {
Log.e("TwitterFeedActivity", "Error loading JSON", e);
}
return tweets;
}
EDIT: I added my LoadTweets() in my doInBackgroundMethod and that solved my problems!
Try declaring the ProgressDialog dialog in the main class in which your AsyncTask class exists and only call the dialog.show and dialog.dismiss method in the AsyncTask class.
Use onCreateDialog(int id) in activity to create ProgressDialog. In AsyncTask call:
MainActivity.this.showDialog(PROGRESS_DIALOG_ID);
To dismiss:
MainActivity.this.dismissDialog(PROGRESS_DIALOG_ID);
Dialogs are connected with activity's context. When activity is recreated dialog should be recreated too but then instance of the dialog is not the same.
I had the same problems and yeah this happened to me when onPostExecute didn't match the declaration... try something like protected Void onPostExecute(Void... arg0)
Next thing to do is to put Log.d("Your app", "Location of this code"); and check which part doesn't execute on Log file ...
Hope u will find the solution...
onPostExecute() does not match the declaration Void. I am on the road so off the top of my head consider:
protected void onPostExecute(Void result)
More here.
Hmm, two things come to mind here..
1) Why is your onPostExecute not overridden like the onPreExecute and doInBackground?
2) Why is the doInBackground after the onPost Execute? Generally the order is
onPreExecute
doInBackground
onPostExecute