My loging async task does the login process, it takes the user input, send it via webservices, verify it, and sends a session id if the user login detail was correct, and returns nothing and also an error if the user login details were wrong, I'm trying to show an alert dialog if the user login details were wrong, my logic is to have an IF statement in onPostExecute that checks if session id field is null or not, if null, it shows an alert dialog and prevent the user from logging in, THIS WORKS, however my issue is that even when the user enters the right detail, it shows the alert dialog box very quickly(flashes), and then directs me to the dashboard, I don't want that alert dialog to show even if it was for seconds, I think that it doesn't ready my IF statement
Thats my Login.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_login);
LB = (Button) findViewById(R.id.loginbutton);
LB.setOnClickListener(this);
}
public void onClick(View view){
switch (view.getId()){
case R.id.loginbutton: //When login button is clicked
new LongOperation().execute(""); //Starts the method called LongOperation
break;
}
}
public class LongOperation extends AsyncTask<String, Void, String>{ //string, void, string was added automatically
#Override
protected void onPreExecute() {
super.onPreExecute();
pdia = new ProgressDialog(Login.this);
pdia.setMessage("Loading...");
pdia.show();
}
#Override
protected String doInBackground(String... params) {
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode
Editor editor = pref.edit();
editor.clear();
editor.commit();
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
usersusername = (EditText)findViewById(R.id.editusername);
userspassword = (EditText)findViewById(R.id.editpassword);
String user_Name = usersusername.getText().toString();
String user_Password = userspassword.getText().toString();
editor.putString("username",user_Name);
editor.commit();
PropertyInfo unameProp =new PropertyInfo();
unameProp.setName("userName");//Define the variable name in the web service method
unameProp.setValue(user_Name);//set value for userName variable
unameProp.setType(String.class);//Define the type of the variable
request.addProperty("username",user_Name);//Pass properties to the variable
//Using this to add parameters "username" grabbed from WSDL
PropertyInfo passwordProp =new PropertyInfo();
passwordProp.setName("password");
passwordProp.setValue(user_Password);
passwordProp.setType(String.class);
request.addProperty(passwordProp);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); // Declare the version of the soap request
envelope.setOutputSoapObject(request);
try {
HttpTransportSE aht = new HttpTransportSE(URL);
aht.call(SOAP_ACTION, envelope);
SoapPrimitive result =(SoapPrimitive)envelope.getResponse();
String SessionID= result.toString();
if (!TextUtils.isEmpty(SessionID))
{
Intent intent = new Intent(Login.this,Dashboard.class);
startActivity(intent);
}
}
catch (Exception e){
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String Something) {
pdia.dismiss();
super.onPostExecute(Something);
if(usersusername.getText().length()==0) {
usersusername.setError("Please enter your username");
}
if(userspassword.getText().length()==0) {
userspassword.setError("Please enter your password");
}
if(Something == null) {
Builder builder = new Builder(Login.this);
builder.setMessage("Invalid login details");
builder.setPositiveButton(R.string.ok_button, null);
builder.create().show();
// show dialog and prepare the fields for retry
}
}
}
}
In your webservice create a checker, like an integer success where if its 1 it successfully queried but if 0 it didn't query. Retrieve it in your asynctask then check in post execute if success == 1 go to dashboard if success == 0 call dialog.
Btw try using the new android Volley for networking as AsyncTask is prone to memory leaks. Cheers! :)
Related
I am trying to load progressBar as dialog while the client app send some data to server and dismiss the bar when data is received back from server.The below code has implemented this model.. with and interface being implemented inside an activity.
private void setup(){
ConnectionHandler connectionHandler = new ConnectionHandler() {
#Override
public void onSendData(){
runOnUiThread(new Runnable() {
#Override
public void run() {
progressDialog = new ProgressDialog(SignupActivity.this);
Log.d("progress bar", "getData: true" );
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setTitle("Loading..");
progressDialog.setMessage("Please wait");
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(true);
progressDialog.show();
}
});
}
#Override
public void onReceiveData(List<Model> model) {
//do nothing for now
LoginMessage message = (LoginMessage)model.get(0);
if(message.getUserCode() != 0){
//registration successfull prompt to verify code;
Log.d("LoginMessage", "onListUpdate: " + message.toJson());
Intent intent = new Intent(getBaseContext(), VerificationActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra(getString(R.string.login_message),message.toJson());
intent.putExtra("email", credentials.getEmail());
progressDialog.dismiss();
startActivity(intent);
}else{
//something went wrong;
}
}
#Override
public Class<? extends Model> getType() {
return LoginMessage.class;
}
};
connectivity = new Connectivity(this, Properties.LOCALHOST + Properties.REGISTRATION_PHP);
connectivity.setConnectionHandler(connectionHandler);
}
The setup method is called when activity is created and connectivity is responsible for calling the onSendData() and onReceiveData().Everything was working fine untill i decided to have progressBar to make client wait for the data to load. Here the error is thrown saying android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application. I followed the solution shown in the other similar problem but didn't worked for me.
Some advised to use
progressBar = new ProgressBar(Activity.this) instead of
progressBar = new ProgressBar(getApplicationContext()) or new ProgressBar(getBaseContext)
but none of them worked for me.What is this error actually is saying to me.
Why is this error thrown?? please help
I am using this code to load data from online database to my android application .
I am wondering what can i add to make this code better ?
Sometimes the progress dialog keeps spinning and never gets the data, the application is stuck then, any ideas on how i can prevent that ?
class LoadAllSections extends AsyncTask<String, String, String>
{
// make a progress dialog appear with the selected specifics
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Loading all sections, please wait");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
// in the background run this code to retrieve data from the server
protected String doInBackground(String... args)
{
List<NameValuePair> params = new ArrayList<NameValuePair>();
JSONObject json = jParser.makeHttpRequest(url_Sections,"POST", params);
try
{
int success = json.getInt(TAG_SUCCESS);
sections = json.getJSONArray(TAG_SECTIONS);
if (success == 1)
{
for (int i = 0; i < sections.length(); i++)
{
JSONObject c = sections.getJSONObject(i);
section_id = c.getString(TAG_SECTION_ID);
section_name = c.getString(TAG_SECTION_NAME);
section_desc = c.getString(TAG_SECTION_DESC);
section_image = c.getString(TAG_SECTION_IMAGE);
section_valid = c.getString(TAG_SECTION_VALID);
HashMap <String,String> sectionmap = new HashMap<String,String>();
sectionmap.put(TAG_SECTION_ID, section_id);
sectionmap.put(TAG_SECTION_NAME, section_name);
sectionmap.put(TAG_SECTION_DESC, section_desc);
sectionmap.put(TAG_SECTION_IMAGE, section_image);
sectionmap.put(TAG_SECTION_VALID, section_valid);
sectionlist.add(sectionmap);
}
}
else
{
finish();
}
}
catch (JSONException e)
{
e.printStackTrace();
}
return null;
}
// disable the progress dialog and load data to the gridview
protected void onPostExecute(String file_url)
{
pDialog.dismiss();
adapter=new SectionAdapter(MainActivity.this,sectionlist);
SectionsGridView.setAdapter(adapter);
}
}
I wanted to add a comment, but I am not allowed to.
Don't have enough reputation :-(
Pass url_section as argument to doInBackground instead of making it global.
I would place the httpRequest insde a try catch block.
Did you set the timeout, if the httpRequest is not answering? I would set that to
60 seconds. I think by default this is set to 600 seconds.
Why do you pass the file_url to onPostExecute instead of passing the
sectionList?
Take a look at AsyncTask. If you don't want to pass anything between the methods, you can also use Void. So in your case AsyncTask would also do it.
Introduction
What I want to accomplish [sounds] simple. I want to prompt a user with a login dialog until the user successfully authenticates.
What I planned to do is use an AsyncTask for the data handling and web requests, but this has turned into a nightmare quickly; most likely due to my lack of experience in Android.
However, I know this can be done, as I've seen it before in other apps.
What I want to accomplish
The question is how? I know what I want to do:
1. Initially prompt a user to login.
2. Send authentication data.
3. If successful, continue the application.
4. If unsuccessful, reprompt the user until success.
What I have so far
What I have so far is my AsyncTask (LoginTask) which will handle the web requests and login data:
public class LoginTask extends AsyncTask<String, Void, App.STATUS>
{
private boolean m_proceed = false;
private String m_username, m_key;
#Override
protected void onPreExecute()
{
// Check if there is a dialog on screen. //
m_proceed = !App.DIALOG_ONSCREEN;
}
#Override
protected App.STATUS doInBackground(String ... p_args)
{
// Do not do this if a dialog is on screen. //
if(!m_proceed)
return App.STATUS.DENIED;
// Make a web request. //
try
{
URL t_url = new URL("https://mysite.com/api/login");
HttpsURLConnection t_con = (HttpsURLConnection)t_url.openConnection();
t_con.setRequestMethod("POST");
t_con.setRequestProperty("User-Agent", "Mozilla/5.0");
t_con.setDoOutput(true);
DataOutputStream t_wr = new DataOutputStream(t_con.getOutputStream());
t_wr.writeBytes("username="+p_args[0]+"&password="+p_args[1]);
t_wr.flush();
t_wr.close();
t_con.connect();
BufferedReader t_in = new BufferedReader(new InputStreamReader(t_con.getInputStream()));
String t_input_line;
StringBuffer t_response = new StringBuffer();
while((t_input_line = t_in.readLine()) != null)
{
t_response.append(t_input_line);
}
t_in.close();
// If denied, return failed. If accepted, set the username and key. //
if(t_response.toString().equals("DENIED"))
return App.STATUS.FAILED;
else
{
m_key = t_response.toString();
m_username = p_args[0];
}
return App.STATUS.ACCEPTED;
}
catch(Exception err)
{
System.err.println(err.getMessage());
}
return App.STATUS.FAILED;
}
#Override
protected void onPostExecute(App.STATUS p_status)
{
// Authenticate the user if the username and key are valid. //
if(p_status == App.STATUS.ACCEPTED)
App.acceptCredentials(m_username, m_key);
// The dialog is no longer on the screen. //
App.DIALOG_ONSCREEN = false;
}
}
And the main activity (HomeActivity) which will prompt the user if they are not authenticated, and will show content if they are:
public class HomeActivity extends Activity
{
#Override
public void onCreate(Bundle p_data)
{
// Basic crap... //
super.onCreate(p_data);
setContentView(R.layout.activity_home);
// Are we authenticated? //
if(!App.isAuthenticated())
{
// Create the dialog. //
LayoutInflater t_infl = LayoutInflater.from(this);
View t_login_view = t_infl.inflate(R.layout.login_dialog, null);
AlertDialog.Builder t_builder = new AlertDialog.Builder(this);
t_builder.setTitle("Login").setView(t_login_view).setPositiveButton("Login", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
// What should go here? //
}
});
t_builder.create();
}
// How do I keep checking if the user is not authenticated, and keep showing the dialog as such? //
}
}
What I need help with
My main question is how do I design my program in such a way that I can easily keep displaying the login dialog until the user has successfully authenticated? I thought of using a while loop, but then it would keep displaying dialogs and hamper performance. It's pretty tricky when I have asynchronous and synchronous tasks working in tandem.
I'm not looking for straight code, but general insight would be much appreciated.
Thank you for taking your time to read this and thank you for helping!
The solution
HomeActivity.java
private void promptLogin()
{
final Context t_main_context = this;
// Create the dialog. //
LayoutInflater t_infl = LayoutInflater.from(this);
final View t_login_view = t_infl.inflate(R.layout.login_dialog, null);
final AlertDialog t_dialog = new AlertDialog.Builder(this)
.setTitle("Login")
.setCancelable(false)
.setView(t_login_view)
.setPositiveButton("Login", null)
.create();
t_dialog.show();
t_dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View t_view)
{
String t_username = ((EditText)t_login_view.findViewById(R.id.in_username)).getText().toString(),
t_password = ((EditText)t_login_view.findViewById(R.id.in_password)).getText().toString();
try
{
new LoginTask(t_main_context, t_dialog).execute(t_username, t_password);
}
catch(Exception err)
{
err.printStackTrace();
}
}
});
}
#Override
public void onCreate(Bundle p_data)
{
// Basic crap... //
super.onCreate(p_data);
setContentView(R.layout.activity_home);
// Are we authenticated? //
if(!App.isAuthenticated())
promptLogin();
}
LoginTask.java
private String m_username, m_key;
private Context m_context;
private AlertDialog m_dialog;
private ProgressDialog m_loading;
public LoginTask(Context p_context, AlertDialog p_dialog)
{
m_context = p_context;
m_dialog = p_dialog;
m_loading = ProgressDialog.show(m_context, "", "Logging in...", true);
}
#Override
protected App.STATUS doInBackground(String ... p_args)
{
// Make a web request. //
try
{
URL t_url = new URL("https://mysite.com/api/login");
HttpsURLConnection t_con = (HttpsURLConnection)t_url.openConnection();
t_con.setRequestMethod("POST");
t_con.setRequestProperty("User-Agent", "Mozilla/5.0");
t_con.setDoOutput(true);
DataOutputStream t_wr = new DataOutputStream(t_con.getOutputStream());
t_wr.writeBytes("username="+p_args[0]+"&password="+p_args[1]);
t_wr.flush();
t_wr.close();
t_con.connect();
BufferedReader t_in = new BufferedReader(new InputStreamReader(t_con.getInputStream()));
String t_input_line;
StringBuffer t_response = new StringBuffer();
while((t_input_line = t_in.readLine()) != null)
{
t_response.append(t_input_line);
}
t_in.close();
// If denied, return failed. If accepted, set the username and key. //
if(t_response.toString().equals("DENIED"))
return App.STATUS.FAILED;
else
{
m_key = t_response.toString();
m_username = p_args[0];
}
return App.STATUS.ACCEPTED;
}
catch(Exception err)
{
System.err.println(err.getMessage());
}
return App.STATUS.FAILED;
}
#Override
protected void onPostExecute(App.STATUS p_status)
{
m_loading.dismiss();
// Authenticate the user if the username and key are valid. //
if(p_status == App.STATUS.ACCEPTED)
{
App.acceptCredentials(m_username, m_key);
m_dialog.dismiss();
}
else
Toast.makeText(m_context, "Login failed", Toast.LENGTH_SHORT).show();
}
So what I did in promptLogin() in HomeActivity.java was that I overrode the button onClickListener, so that the dialog would not close unless closed by t_dialog.dismiss(). I then sent the web request to LoginTask and passed the dialog as a parameter, so that the dialog would only close until I dismissed the dialog.
I only dismiss the dialog when the credentials are accepted, as you can see in onPostExecute().
In this way, the dialog stays on screen until the user successfully logs in, which is the behavior I was looking for.
Thanks everyone for helping!
1. Initially prompt a user to login.
keep prompting the dialog here, with setCancelable(false), so the user will not cancel the login process. Then create a View.OnclickListner on the button that the user have to click on in order to send data to your server. Let's say Login button.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Delete entry")
.setMessage("Are you sure you want to delete this entry?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// send data here with AsyncTask
}
})
.setIcon(R.drawable.ic_my_icon);
builder.setCancelable(false);
builder.show();
2. Send authentication data.
Use your AsyncTask here, do the sending task in doInBackgroud() method, and return something onPostExecute() to know if authentication succeeded or not. if success, dismiss the dialog, if not, you keep the dialog and wait for the user to click again the Login button.
protected void onPostExecute(Boolean result) {
if(result) {
// he is now authenticated, dismiss dialog and continue in your app
dialog.dismiss();
} else {
// nothing to do, until he succeed
}
}
3. If successful, continue the application.
Dismiss the dialog here buy using the dismiss() method.
4. If unsuccessful, reprompt the user until success.
Don't do anything, let the dialog shown, until the authentication process succeeds. You can also show something to the user (a toast, an image etc) to tell him that he hasn't logged in yet.
Hope it's clear for you.
You have to create one activity which handles your login, and another which is your main activity. If the login fails, nothing happens, if it succeeds you start the second activity. No need for your complicated setup.
You can also have a look at the Volley library, makes http connections pretty easy.
The app I am working on has a login/register which connects to a mysql database, At first I was running everything on the UI Thread I later found out it was not working because of the against running long code on Android's UI Thread. I attempted to edit my code to run the long task on a new Thread that i added.
. Now my app registers the I see the result in mysql but my app keeps closing because of this error
android.view.ViewRootImpl$CalledFromWrongThreadException:
Only the original thread that created a view hierarchy can touch its views.
the error is understandable but I don't know how to run the View or Views back to the UI Thread.
I've done some research about the runOnuithread but I dont know where to place it in my code, or weather I placed the new Thread I added before in the wrong place to begin with please
can anyone help my fix this
here is a snippet of the code
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.register);
// Importing all assets like buttons, text fields
inputFullName = (EditText) findViewById(R.id.registerName);
inputEmail = (EditText) findViewById(R.id.registerEmail);
inputPassword = (EditText) findViewById(R.id.registerPassword);
btnRegister = (Button) findViewById(R.id.btnRegister);
btnLinkToLogin = (Button) findViewById(R.id.btnLinkToLoginScreen);
registerErrorMsg = (TextView) findViewById(R.id.register_error);
// Register Button Click event
btnRegister.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
/** According with the new StrictGuard policy, running long tasks on the Main UI thread is not possible
So creating new thread to create and execute http operations */
new Thread (new Runnable() {
#Override
public void run() {
//
String name = inputFullName.getText().toString();
String email = inputEmail.getText().toString();
String password = inputPassword.getText().toString();
UserFunctions userFunction = new UserFunctions();
JSONObject json = userFunction.registerUser(name, email, password);
// check for login response
try {
//
//
if (json.getString(KEY_SUCCESS) != null) {
registerErrorMsg.setText("");
String res = json.getString(KEY_SUCCESS);
if(Integer.parseInt(res) == 1){
// user successfully registred
// Store user details in SQLite Database
DatabaseHandler db = new DatabaseHandler(getApplicationContext());
JSONObject json_user = json.getJSONObject("user");
// Clear all previous data in database
userFunction.logoutUser(getApplicationContext());
db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT));
// Launch Dashboard Screen
Intent dashboard = new Intent(getApplicationContext(), MainActivity.class);
// Close all views before launching Dashboard
dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(dashboard);
// Close Registration Screen
finish();
}else{
// Error in registration
registerErrorMsg.setText("Error occured in registration");
}
}//
} catch (JSONException e) {
e.printStackTrace();
}
}
}).start();
}
});
// Link to Login Screen
btnLinkToLogin.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent i = new Intent(getApplicationContext(),
LoginActivity.class);
startActivity(i);
// Close Registration View
finish();
}
});
}
}
Since you seem to have network code mixed in with UI code, I'm not going to try and write it for you. I can tell you how it should be and assume that you can rearrange the code yourself since you know what all of it does.
Ok, inside your run() you put your network code then when you need to update the UI you can have
runOnUiThread(new Runnable()
{
#Override
public void run()
{
// code to update UI
}
});
With that said, I recommend using AsyncTask for your network operations. This makes it much easier as it already has the functions for background stuff and updating the UI. You start the task and doInBackground() runs and that is where you do all of your network operations. Then you can update the UI in any of AsyncTasks other 3 methods.
See this answer for an example of using AsyncTask, along with the link to the docs above.
I couldn't think of a way to form my title to make my issue obvious, so here goes:
I'm a little over my head with diving into AsyncTask for the first time. I currently have an app that simply sends a tweet. To do this it must kick out to a WebView for Twitter authorization, which comes back to onNewIntent().
What I'm trying to do is throw up a simple Spinner ProgressDialog while it's connecting to the site/performing the AccessToken work, and then again while it's sending the tweet. I've only just discovered that I will need a new thread for the progress bar. Or rather, that I should be doing my "time-intensive work" in it's own separate thread to make using a ProgressDialog viable. My question is this: How can I have my progress spinner in the foreground while my authorization code works in the background, and eventually opens the WebView and comes back, and ultimately starts everything over at onResume()?
I'm sure I'm probably not doing everything else in the most proper fashion. I'm new to Android, but not to Java. I've put in my create- and dismissDialog(int) calls about where they should be, procedurally. As-is, everything otherwise works the way it should, but obviously my dialogs are simply not able show themselves.
I'm thinking I should basically put my entire authorize() and tweet() methods into their own AsyncTask. I'm just not sure how to go about that, especially since authorize() (or more specifically, loginToTwitter()) needs to end up saving the data it gets from the browser to shared preferences after it comes back to onNewIntent().
Thanks for any insights,
== Matt
public class IntegrateTwitter extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
protected void onResume() {
super.onResume();
mPrefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
mTwitter = new TwitterFactory().getInstance();
mTwitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
if(authorize()) {
tweet();
returnToMM();
}
}
private boolean authorize() {
Log.i(LOG_TAG, "Authorizing...");
showDialog(PD_AUTHORIZING);
boolean result = false;
if(responseExistsAndValid()) {
saveResponseToAccessToken();
}
if(isAuthorized()) {
Log.i(LOG_TAG, "Prefs have AccessToken, grabbing it...");
if(getAccessTokenFromPrefs()) {
Toast.makeText(IntegrateTwitter.this, "Authorized.", Toast.LENGTH_SHORT).show();
result = true;
}
}
else {
Log.i(LOG_TAG, "Prefs don't have AccessToken.");
if(!responseStringExists()) {
Log.i(LOG_TAG, "No response exists either, starting Twitter login process...");
Toast.makeText(IntegrateTwitter.this, "Authorizing...", Toast.LENGTH_SHORT).show();
// Here is where it kicks out to the browser for authentication
loginToTwitter();
}
else {
Toast.makeText(IntegrateTwitter.this, "Authorization failed.", Toast.LENGTH_SHORT).show();
Log.i(LOG_TAG, "Response exists, so it must have failed once already, skipping Twitter login process.");
returnToMM();
}
}
deleteResponseFromPrefs();
dismissDialog(PD_AUTHORIZING);
return result;
}
private void tweet() {
showDialog(PD_TWEETING);
try {
Date testDate = new Date();
String testDateString = DateFormat.format("yyyy-MM-dd # hh:mm:ss", testDate.getTime()).toString();
mTwitter.updateStatus(testDateString + " Test Tweet");
Toast.makeText(this, "Tweet successful!", Toast.LENGTH_SHORT).show();
}
catch (TwitterException e) {
Toast.makeText(this, "Tweet error.", Toast.LENGTH_SHORT).show();
Log.i(LOG_TAG, e.getMessage());
Log.i(LOG_TAG, Arrays.toString(e.getStackTrace()));
}
dismissDialog(PD_TWEETING);
}
// A bunch of support methods
// ...
}
Try this.....
I think you know that if we are not using AsyncTask, we can always use Thread along with Handler, to Post the work done on Non-UI thread to UI thread.
AsyncTask is provided by android to sync the UI and Non-UI work seamlessly.
I got this example by searching on Google, but changed it the way you wanted it to be.
Here it will Count till 50... and until it does it will keep displaying the ProgressDialog.
Please see the log while the program is executing to see the count increasing till 50.
public class AsyncTaskExampleActivity extends Activity
{
protected TextView _percentField;
protected Button _cancelButton;
protected InitTask _initTask;
ProgressDialog pd;
#Override
public void onCreate( Bundle savedInstanceState )
{
super.onCreate(savedInstanceState);
setContentView( R.layout.main );
_percentField = ( TextView ) findViewById( R.id.percent_field );
_cancelButton = ( Button ) findViewById( R.id.cancel_button );
_cancelButton.setOnClickListener( new CancelButtonListener() );
_initTask = new InitTask();
pd = ProgressDialog.show(AsyncTaskExampleActivity.this, "Loading", "Please Wait");
_initTask.execute( this );
}
protected class CancelButtonListener implements View.OnClickListener
{
public void onClick(View v) {
_initTask.cancel(true);
}
}
/**
* sub-class of AsyncTask
*/
protected class InitTask extends AsyncTask<Context, Integer, String>
{
// -- run intensive processes here
// -- notice that the datatype of the first param in the class definition matches the param passed to this method
// -- and that the datatype of the last param in the class definition matches the return type of this method
#Override
protected String doInBackground( Context... params )
{
//-- on every iteration
//-- runs a while loop that causes the thread to sleep for 50 milliseconds
//-- publishes the progress - calls the onProgressUpdate handler defined below
//-- and increments the counter variable i by one
int i = 0;
while( i <= 50 )
{
try{
Thread.sleep( 50 );
publishProgress( i );
i++;
} catch( Exception e ){
Log.i("makemachine", e.getMessage() );
}
}
pd.dismiss();
return "COMPLETE!";
}
// -- gets called just before thread begins
#Override
protected void onPreExecute()
{
Log.i( "makemachine", "onPreExecute()" );
super.onPreExecute();
}
// -- called from the publish progress
// -- notice that the datatype of the second param gets passed to this method
#Override
protected void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
Log.i( "makemachine", "onProgressUpdate(): " + String.valueOf( values[0] ) );
_percentField.setText( ( values[0] * 2 ) + "%");
_percentField.setTextSize( values[0] );
}
// -- called if the cancel button is pressed
#Override
protected void onCancelled()
{
super.onCancelled();
Log.i( "makemachine", "onCancelled()" );
_percentField.setText( "Cancelled!" );
_percentField.setTextColor( 0xFFFF0000 );
}
// -- called as soon as doInBackground method completes
// -- notice that the third param gets passed to this method
#Override
protected void onPostExecute( String result )
{
super.onPostExecute(result);
Log.i( "makemachine", "onPostExecute(): " + result );
_percentField.setText( result );
_percentField.setTextColor( 0xFF69adea );
_cancelButton.setVisibility( View.INVISIBLE );
}
}
}