I have a class that sends various mail with attachments.
Because the method sendEmail(addresses);
requires time to upload the attachments and send the emails, I have created an AsyncTask to show a waiting dialog,
however, unfortunately, during the sending the app freezes until it has terminated the sending without showing anything (or sometimes shows a frozen waiting windows for a little instant before the end of procedure)
The related parts of code in my class are the follows
public class MyClass extends Activity {
...
private ProgressDialog waitingDialog;
....
OnClickListener mInvia = new OnClickListener() {
public void onClick(View v) {
new MyAsyncTaskClass().execute(new String[] {});
}
};
public void prepareSending() {
String x = "";
for (String s : selectedMails) {
x += (s + ";");
}
String[] addresses = x.split(";");
sendEmail(addresses);
}
private void openFile() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.setType("file/*");
startActivityForResult(i, FILE_REQ_CODE);
}
protected void onActivityResult(int requestCode, int resultCode,
Intent intentData) {
Uri tmp = intentData.getData();
filePath=getRealPath(tmp);
super.onActivityResult(requestCode, resultCode, intentData);
}
public void sendEmail(String[] addresses) {
Mail m = new Mail("sendermail@sample.com",
"senderpassword");
name = editor1.getText().toString();
subject = editor2.getText().toString();
text = editor3.getText().toString();
emailReply = editor4.getText().toString();
m.setTo(addresses);
m.setFrom(emailReply);
m.setSubject(subject);
m.setBody(text + "\n\n\n Sent by" + name);
try {
m.send();
} catch (Exception e) {
Log.e("MyClass", "Cannot send email", e);
}
try {
m.addAttachment(filePath);
if (m.send()) {
Alerts.Ok(MyClass.this);
nSuccess++;
} else {
Alerts.ErrorSending(MyClass.this);
}
} catch (Exception e) {
Alerts.ErrorAttachment(MyClass.this);
}
}
//inner class that should show a waiting windows
private class MyAsyncTaskClass extends AsyncTask<String, Void, Void> {
@Override
protected void onPreExecute() {
waitingDialog = new ProgressDialog(MyClass.this);
waitingDialog.setMessage("Loading ....");
waitingDialog.setIndeterminate(true);
waitingDialog.setCancelable(true);
waitingDialog.show();
}
@Override
protected Void doInBackground(final String... strings) {
try {
runOnUiThread(new Runnable() {
public void run() {
prepareSending();
}
});
} catch (Exception e) {
}
return null;
}
@Override
protected void onPostExecute(Void params) {
waitingDialog.dismiss();
}
}
//end innerclass
// start context menu code
......
}
I'd wager it's because you're running everything on the UI thread:
@Override
protected Void doInBackground(final String... strings) {
try {
runOnUiThread(new Runnable() {
public void run() {
prepareSending();
}
});
} catch (Exception e) {
}
return null;
}
Run all your doInBackground
code based on non-UI-reliant things.
@Override
protected Void doInBackground(final String... strings) {
prepareSending();
return null;
}
If you need to access data from the UI, or anything else on the UI thread, do that first.
protected void onPreExecute() {
// Find all your "editor" fields here, and save them to member variables within the AsyncTask.
// ...
}
In prepareSending
and sendEmail
accept that data as parameters:
public void prepareSending(String name, String subject, String text, String emailReply) {
// ...
sendEmail(addresses, name, subject, text, emailReply);
}
public void sendEmail(String[] addresses, String name, String subject, String text, String emailReply) {
// ...
}
And lastly, you need to send those from doInBackground
:
@Override
protected Void doInBackground(final String... strings) {
prepareSending(mName, mSubject, mText, mEmailReply); // The local fields you saved earlier
return null;
}