I have code like this
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
boolean autoLogin = false;
autoLogin = checkAutoLogin();
if(autoLogin) {
showProgress();// Show progress dialog
if(login(savedUserName,savedPassword)) {
//call home activity using startActivity();
}
// login(savedUserName,savedPassword), this function access the server and return true if username and password correct- this works properly
}
}
Now the question is, i get display of home activity without displaying main activity and its progress dialog, during the authentication time of login(savedUserName,savedPassword)(this function take countable time because of server authentication) function, I got only a black screen, during this time i want show main activity and progress dialog.
Note:If i click back button in home activity i can get main activity and progress dialog
You should not do the network operation on UI thread,you can do it in separate thread and then you can call the home activity using Handler object,it iwll solve your problem
Do your Time Consuming Task in the AsynchTask. this class is designed exactly for the kind of work you are looking for.Use doInBackground() method to accomplish the task and onPreExecute you can show a progress Dialog.
Depending on what your showProgress() method contains, I'd guess that showProgress runs, sees that there is no active login attempt happening, and dismisses itself, then the login() method is called.
What you want to do is start login() asynchronously and then start the progress dialog that will check to see if login() is finished.
This is just a guess from what I can see of your code.
Could you post some more of it perhaps?
Try putting some logcat logging into the showProgress() method to see if it is in fact being created and destroyed quickly.
Related
My app requires people to log in with Facebook. Once they have done so, the Facebook token is checked each time they open the app so that we do not ask them to sign in again - we redirect them straight to the MainActivity.
Note that this is an 'empty view' activity - I have not used setContentView to set it to a view, it is purely there for decision making.
public class DecisionActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getApplicationContext());
if (AccessToken.getCurrentAccessToken() != null) {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
} else {
Intent startIntent = new Intent(this, SignUpActivity.class);
startActivity(startIntent);
finish();
};
}
}
This is my MainActivity code. Notice that I call my network operations in onCreate because I do not want to call them each time I minimize my app and maximize my app when the activity onResumes. It must be called once when I create my activity.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//show my progress bar
//CALL MY API TO GET SOME DATA FROM THE SERVER
//hide my progress bar after data is received.
}
}
This works perfectly. If the user has signed in, he is redirected to my MainActivity everytime. If the user hasn't signed in, he goes to SignUpActivity.
However, there is one nasty side effect from this code that I discovered today. Scenario 1 on onResuming my app works the way I want it to work.
Scenario 2 on onResuming my app does not work the way I want it to work.
Scenario 1:
If you are in your MainActivity and you minimize your app and press the square button, find your app and maximize again, the MainActivity onCreate method will not be called as the activity simply onResumes therefore no network operations is performed, progress bar is not shown, which is what I want.
Scenario 2:
However, if you minimize your app and decide to click on the app icon on your phone, DecisionActivity will be launched which will decide that MainActivity needs to be launch as the user has logged in already and the token exists. Because MainActivity is relaunched, onCreate is called and network activities are performed and the progress bar is shown, which is not what I want.
How do I stop this from happening when I click on my app icon on my phone?
I checked popular apps like Facebook now to see if they have the same issue by testing Scenario 1 and Scenario 2 on them and they don't seem to encounter this problem which makes me think whether the setup I have used to check whether someone has logged into my app under DecisionActivity can be done in a better way.
I'm sure a more elegant way exists, but this is what I have off the top of my head:
Try using SharedPreferences. So, when your app is minimized, the onPause() method is called. In this method, set the SharedPreference to false, which means that you don't wanna run the progress bar right now. Check for that SharedPreference in your MainActivity's onCreate() method. When the app is resumed, set the SharedPreference to true.
So this means that whenever the user went through the onPause() method, the progress bar won't run either if he goes through the Scenario 1 (because then he will hit onResume(), which won't show the progress bar) or if he goes through Scenario 2 (because your SharedPreference is false, and you check for its value beforehand in MainActivity's onCreate()).
But, now you also have to use the onFinish() or the onDestroy() method, and change the value of your SharedPreference to true, which will make the progress bar to appear when the app is launched next time.
The only flaw I can think of is that I'm not sure whether the onDestroy() method would be called if the user closes the app from the Recents Menu, or if Android mamory cleaner closes the app to free up memory, so do try it and tell me if it works.
And I agree this is but more of a hack and not a proper solution, but if it works, it is good enough ;)
i have activity take long time until get loading so i want when i click start this activity to show loading message like ( loading..... )
here is the button that started this activity
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(test.this, MainActivity.class);
startActivity(intent);
}
});
so what the code that should i write here to show this loading message until the MainActivity load?
If you have activity A that on click shows activity B that takes long time to load, the most common way is this:
in the activity B layout view have a progress bar and make it visible in onCreate of activity B
all long running operations put either in a asyncTask or in some Service that would run in the background
when long running operation finishes - update progress bar by setting it's visibility to View.GONE.
I would write you a code, but since I don't have your code, I think the best way I could help is to break your problem into a steps.
daneejela provided a solution but I do think that the reason for you long startup of your MainActivity is the real problem and should get fixed.
Activities will take long to startup when you do too much block method calls or such things in the MainThread.
Try to do those things in a background Thread (you can use AsyncTask). This will result in an immediate Activity startup. While your AsyncTask is working, you can show a little ProgressDialog or better, show somewhere in your Activity a ProgressBar which is not blocking the user from doing any kind of action.
You should definitly understand Android's Main- and BackgroundThreading. There are also great tutorials for Dialogs. You should also check out the Android Design Guidlines.
I am stumped on this issue, my onBackPressed() method doesn't work when it has to. My scenario is as soon as activity starts, progress dialog shows up because I called asynctask.execute() in onCreate. When the process takes long time I want to give user a feature that he can dismiss the ongoing process(downloading data from the server) so I tried to dismiss the dialog and finish the activity when back button is pressed, but it's not working.
When I normally press back button after I have got the data, then the control seems to be flowing under onBackPressed().
Below is my code snippet:
public void onBackPressed() {
if(progressDialog != null && progressDialog.isShowing())
{
progressDialog.dismiss();
}
finish();
}
Is there any other way to give user an opportunity to cancel that anytime. Please suggest me how to make the entire process and activity terminated when the user presses back button.
For canceling the progress dialogue please set progress dialog cancel as true.
dialog.setCancelable(true);
I'm trying to setup UI where user will have to login first time they use applications. And Custom Dialog seems like a good thing to use as I want main UI to be kind of visible on background.
So, what I did - I created main Activity and use ShowDialog() with onCreateDialog from main activity.
I created
public class LoginDialog extends Dialog implements View.OnClickListener
and I can control all stuff on dialog just like activity.
Ideally I like to check if user logged in on main activity and if not - show this dialog. Otherwise just go with activity.
On dialog I'd like to log user in and if user clicks back without logging in - I want to detect it and just finish main activity. This is where I have problem.
In WinForms I would do ShowDialog() (in C#) and next line executed when dialog closed for any reason. I can't figure out how to do this in Android.
I didn't get to it yet, but I want to show progress bar when Login button clicked. This bar will be in Dialog box. Is it possible/doable?
Thanks in advance!
You can detect dialog dismissal using setOnDismissListener. In this method you could also call MyActivity.this.finish().
For showing a ProgressBar during the login process, you probably want to look at this answer. It shows the basic structure of AsyncTask and you can adapt it to use ProgressBar instead of ProgressDialog.
You would be changing the bar's visibility in onPreExecute and onPostExecute with bar.setVisibility(View.VISIBLE) and bar.setVisibility(View.INVISIBLE).
Edit
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
dialog.dismiss();
if (!isLoggedIn()) {
MyActivity.this.finish();
}
}
});
This code should be in your MyActivity wherever you create the dialog. You need to check to see if the user is logged in or not, because onDismiss will be called whether it's the user or your own code that closes the dialog.
I'm writing an Android application which requires the user to login. I have a "username" and "password" EditText fields and also a "Submit" button.
When testing in the emulator (and on a phone), the app appears to 'lock up' when the user hits "Submit". It hasn't actually crashed or anything like that, it's just locked whilst the connection to the server is made (and then it advances the user to the next view if their login is correct).
This isn't very cosmetically pleasing as some users may think the app has locked up if their connection is slow and the login doesn't process for a few seconds..
To avoid this I want to have a ProgressBar which will appear just to let the user know something is happening and the app hasn't locked up!
Here's my code:
private OnClickListener listenerOne = new OnClickListener() {
public void onClick(View v) {
Button submitButton = (Button)findViewById(R.id.submit);
submitButton.setVisibility(8); //Make submit button invisible
ProgressBar progressBar = (ProgressBar)findViewById(R.id.progressbar);
progressBar.setVisibility(0); //Make progress bar visible. It's in the same position as the submit button
login(); // do the login server stuff
// the problem is that thenew visibility doesn't happen until the login() is called...
}
};
I've ordered the code so that it makes the submit invisible, then makes the progress bar visible, then does the login (so the progress bar will be there twirling around whilst the app connects to the login server). However, it's not working out how I intended - it's seemingly skipping over the setVisibility code and just calling the login method. It must be setting the visibility of the submit and progress bar items but it doesn't happen before the login method does its stuff as it just locks up like usual and the items never actually get hidden/shown until the login method has completed!!
Any help would be much appreciated. Sorry for the essay!
You need to hand control back to the UI thread after changing the ProgressBar visibility and do your login work on another thread. The best way to do this is via AsyncTask.
This answer has a code sample for showing a ProgressDialog while doing a task in the background. You can modify it to call setVisibility on your ProgressBar instead.
The login part is still taking over the UI thread despite being "after" your UI elements.
You should try running it in a separate thread or AsyncTask. Try this for starters (replace your login() call with it), then make it prettier if it works:
new Thread(new Runnable() {
public void run() {
login();
}
}).start();
Any particular reason you are using the actual ints as opposed to the flags available for setting visibility? Seems like it would be easier to read like this:
progressBar.setVisibility(ProgressBar.VISIBLE);