I have a tabgroup having multiple activities. In one of the tabs i have two activities between whom i want to place a progress dialog.For this i am using Asynk Task. Following is my AsynkTask class which i have made an inner class for AboutUs activity:
private class TheTask extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute() {
progDialog = ProgressDialog.show(AboutUs.this.getParent(), "Loading... ",
"please wait....", true);
}
#Override
protected Void doInBackground(Void... params) {
final Intent aboutusIntent = new Intent(getParent(), Departments.class);
final TabGroupActivity parentActivity = (TabGroupActivity)getParent();
parentActivity.startChildActivity("Departments", aboutusIntent);
return null;
}
#Override
protected void onPostExecute(Void result) {
if(progDialog.isShowing())
{
progDialog.dismiss();
}
}
}
I am calling this class in my AboutUs activity :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aboutus);
.
.
.
.
/* Button for going to Departments */
Button ourdepbtn = (Button) findViewById(R.id.departmentsbutton);
ourdepbtn.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
//ourDepartments();
new TheTask().execute();
return false;
}
});
}
However this does'nt start a new activity i.e. Departments. The progress dialog appears and then disappears but activity never loads.
Any suggestions..??
First, you cannot start an activity from a non GUI thread (which Async doInBackground() is). Just start directly inside your Button.onClick() (why you use onTouch?) listener.
If you want to show up a ProgressDialog for the new Activity as soon as possible, you need to create it in the new (child) Activity onCreate(), as your ProgressDialog is connected to the new (child) activity (is it?). Take care about the order of creating layouts (create the ProgressDialog after calling setContentView()).
I am not very sure why you want to show that ProgressDialog. Is there something which delays the display of the childActivity? You loading some data? Then, the Dialog should be related to that loading task (Async I guess).
private class TheTask extends AsyncTask{
Context con;
Intent aboutusIntent;
TabGroupActivity parentActivity;
private TheTask(Context context)
{
this.con=context;
}
#Override
protected void onPreExecute() {
progDialog = ProgressDialog.show(con, "Loading... ",
"please wait....", true);
}
#Override
protected Void doInBackground(Void... params) {
aboutusIntent = new Intent(con, Departments.class);
parentActivity = (TabGroupActivity)getParent();
return null;
}
#Override
protected void onPostExecute(Void result) {
if(progDialog.isShowing())
{
progDialog.dismiss();
}
parentActivity.startChildActivity("Departments", aboutusIntent);
}
}
Thanks for your suggestions Oliver :)
Related
I have attached on click listener to a text view, inside on click listener a function say f1 is called and inside f1 another function say f2 is called.
Inside f2 I have created a android ProgressDialog object using current activity context, and called show function on progressDialog object. ProgressDialog takes time to appear on screen around 5-6 sec.
I have analyzed my code, but not able to understand why it takes this much time ?
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ShowSyncDialog(); - f1
}
});
public void ShowSyncDialog()
{
fnSyncOfflineData(); - f2
}
public void fnSyncOfflineData()
{
ProgressDialog progressDialog = new ProgressDialog(context);
progressDialog.show();
//other code
}
You should call your functions in an AsyncTask. Also ProgressDialog must be shown at the beginning of this works. Use something like this:
public class YourTask extends AsyncTask<String, Void, String> {
private Context mContext;
private ProgressDialog progressDialog;
public YourTask(Context context) {
super();
mContext = context;
progressDialog = new ProgressDialog(context);
progressDialog.setMessage("Your Message");
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.show();
}
#Override
protected String doInBackground(String... values) {
// If you want to use 'values' string in here
String values = values[0];
String yourResult = yourFunction();
return yourResult;
}
#Override
protected void onPostExecute(String result) {
progressDialog.dismiss();
// Your task has done
...
}
}
Then call this task with:
new YourTask(YourActivity.this).execute();
You can change return type of task doInBackground method. This is just an example, you can search about AsyncTask.
Good luck.
I have a MainActivity that has onCreate method in it. In that class, it should load the layout and post data to server. As long as the activity started, it becomes blank and only go to the next activity SignUpActivity. what I need is the MainActivity layout will show first and then execute the httpPost.
Here are my code
public class MainActivity extends Activity {
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
context = this;
new MainAsyncTask().execute(""); // where should i put this code? here??
}
private class MainAsyncTask extends AsyncTask<Object, Integer, String> {
#Override
protected String doInBackground(Object... params) {
String result = null;
String url = "some url";
Log.i("Post", "Post HTTP");
HttpPostHelper.postData(url); // method to post the http. i made myself
intent = new Intent(context, SignUpActivity.class);
startActivity(intent);
return result;
}
}
}
i just want that the MainAsyncTask.execute("") is executed after the layout is fully shown on the device.
SOLVED
I move the new MainAsyncTask().execute(""); and add it here, and it works fine:
#Override
protected void onStart() {
super.onStart();
new MainAsyncTask().execute("");
}
Try in onStart() method of activity
calling on AsynTask seems ok but you shouldn't call your intent in doInBackground()
call it in onPostExecute() method
protected void onPostExecute(String result){
intent = new Intent(context, SignUpActivity.class);
startActivity(intent);
}
You can try a Thread.sleep before startActivity to give the main layout some time to load and show. You should also call the startActivity in onPostExecute.
as per your code it should be like this. Take care of # doinbackground() as here it is not correct.
public class MainActivity extends Activity {
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
context = this;
new MainAsyncTask().execute(""); // where should i put this code? here??
}
private class MainAsyncTask extends AsyncTask<Object, Integer, String> {
protected void onPreExecute( ){
//start Progressbar
progressBar.show();
}
#Override
protected String doInBackground(Object... params) {
String result = null;
String url = "some url";
Log.i("Post", "Post HTTP");
HttpPostHelper.postData(url); // method to post the http. i made myself
return result;
}
protected void onPostExecute(String result){
//stuff u want in main thread
progressBar.cancell();
intent = new Intent(context, SignUpActivity.class);
startActivity(intent);
}
}
}
I've isolated an issue I am having when showing a ProgressDialog while an AsyncTask is executing and then trying to show an AlertDialog when onPostExecute is executed.
The steps to reproduce are:
1-Run the task
2-Before the task has finished press Home button
3-When you assume the task is finished return to the app
4-AlertDialog is not shown and a low bright (like disabled) screen is shown.
I've discovered that moving the dialog.dismiss() line to the end of the onPostExecute method fixes the problem... But this is weird, isn't it?
Source code:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClickButton(View view) {
new MyAsyncTask(this).execute();
}
private class MyAsyncTask extends AsyncTask<Void, Void, Void>
{
ProgressDialog dialog;
Context ctx;
public MyAsyncTask(Context ctx) {
this.ctx = ctx;
}
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(ctx);
dialog.setMessage("Loading");
dialog.show();
}
#Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void value) {
dialog.dismiss();
AlertDialog.Builder alertbox = new AlertDialog.Builder(ctx);
alertbox.setNeutralButton("OK", null);
alertbox.setMessage("Message");
alertbox.setIcon(android.R.drawable.ic_dialog_alert);
alertbox.show();
// dialog.dismiss(); If I remove it from above and put this line here, it will work ok
}
}
}
In my code I load a spinner adapter by using Async Task
In My case The ProgressDialog is Not dismissing
This is My code.
I want to show the item after adapter load and the progressDialog is to dismiss
Please Help me, Thanks
private class LoadMoreVehicals extends AsyncTask<Object, Integer, Object> {
#Override
protected void onPreExecute() {
progressBar = ProgressDialog.show(RegistrationScreen.this, "",
"Loading...");
progressBar.setIndeterminate(true);
progressBar.setIndeterminateDrawable(getResources().getDrawable(
R.anim.progressbar_handler));
super.onPreExecute();
}
#Override
protected Object doInBackground(Object... params) {
String countryUrl = ConstantURL.COUNTRY_URL;
getCounty(countryUrl);
countrySpinner
.setAdapter(new MyCustomSpinnerAdapter(
RegistrationScreen.this,
R.layout.spinner_dropdown,
countyList));
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
progressBar.getProgress();
}
#Override
protected void onPostExecute(Object result) {
progressBar.dismiss();
Log.e("Im in onPostExecute", "");
super.onPostExecute(result);
}
}
While programming in Android you should remember one thing that any task which draws something on the screen should be executed on the main thread. When you set the adapter then android calls the getView() method of the adapter and draws views on the screen. So you should set the adapter in the postExecute() method instead in doInBackground() method.
Here is a small sample to clear my point:
class MyTask extends AsyncTask<Void, Void, Void> {
ProgressDialog pd = new ProgressDialog(MainActivity.this);
#Override
protected void onPreExecute ( )
{
//starting the progress dialogue
pd.show();
}
#Override
protected Void doInBackground (Void... params)
{
//fetch data here
...
...
return null;
}
#Override
protected void onPostExecute (Void result)
{
//set adapter here
...
...
//dismissing the progress dialogue
pd.dismiss();
}
}
In my experience i have so many problems with async runs and UI so now always separate the stuff trying to place the "responsibilities" in each place. So i do something like this:
Create my Async class with the process i want to do and nothing that transform the UI in it
Create a function in UI thread that modify the UI when async task finish, something like OnAsyncTaskComplete(Object response)
Keep communicated the threads
public class MyActivity extends Activity {
private static MyAsyncClass backgroundTask;
private static ProgressDialog pleaseWaitDialog;
//......activity stuff.......
#Override
public void onPause()
{
super.onPause();
//Get rid of progress dialog in the event of a screen rotation or other state change. Prevents a crash.
if (pleaseWaitDialog != null)
pleaseWaitDialog.dismiss();
}
//Function to avoid lose the async thread if the app interrupts (phone rotation, incoming call, etc) RECOMENDED TO HANDLE THIS!!
//Sets the current state after app resume
#Override
public void onResume()
{
super.onResume();
//If there is a background task set it to the new activity
if ((backgroundTask != null) && (backgroundTask.getStatus() == Status.RUNNING))
{
if (pleaseWaitDialog != null)
pleaseWaitDialog.show();
backgroundTask.setActivity(this);
}
}
}
//Logic business after the web service complete here
//Do the thing that modify the UI in a function like this
private void onTaskCompleted(Object _response)
{
//For example _response can be a new adapter
MyList.setAdapter((BaseAdapter)_response);
//or can be a list to create the new adapter
MyList.setAdapter(new MyAdapter(this, (ArrayList<String>)_response));
//or can be anything you want, just try to make here the things that you need to change the UI
}
/**
* Class that handle the async task
*/
public class MyAsyncClass extends AsyncTask<Void, Void, Object>
{
//Maintain attached activity for states change propose
private MyActivity activity;
//Keep the response of the async task
private Object _response;
//Flag that keep async task completed status
private boolean completed;
//Constructor
private MyAsyncClass(MyActivity activity) {
this.activity = activity;
}
//Pre execution actions
#Override
protected void onPreExecute() {
//Start the splash screen dialog
if (pleaseWaitDialog == null)
pleaseWaitDialog= ProgressDialog.show(activity.this,
"PLEASE WAIT",
"Getting results...",
false);
}
//Execution of the async task
protected Object doInBackground(Object...params)
{
//return the thing you want or do want you want
return new ArrayList();
}
//Post execution actions
#Override
protected void onPostExecute(Object response)
{
//Set task completed and notify the activity
completed = true;
_response = response;
notifyActivityTaskCompleted();
//Close the splash screen
if (pleaseWaitDialog != null)
{
pleaseWaitDialog.dismiss();
pleaseWaitDialog = null;
}
}
//Notify activity of async task completion
private void notifyActivityTaskCompleted()
{
if ( null != activity ) {
activity.onTaskCompleted(_response);
}
}
//for maintain attached the async task to the activity in phone states changes
//Sets the current activity to the async task
public void setActivity(MyActivity activity)
{
this.activity = activity;
if ( completed ) {
notifyActivityTaskCompleted();
}
}
}
}
Hope its help you
First of all you cannot set the adapter in the doInBackground
follow this design:
private class LoadMoreVehicals extends AsyncTask<Object, Integer, Object>
{
private ArrayList<Country> countries;
#Override
protected void onPreExecute() {
progressBar = ProgressDialog.show(RegistrationScreen.this, "","Loading...");
progressBar.setIndeterminate(true);
progressBar.setIndeterminateDrawable(getResources().getDrawable(R.anim.progressbar_handler));
super.onPreExecute();
}
#Override
protected Object doInBackground(Object... params) {
String countryUrl = ConstantURL.COUNTRY_URL;
countries = getCounty(countryUrl);
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
progressBar.getProgress();
}
#Override
protected void onPostExecute(Object result) {
countrySpinner.setAdapter(new MyCustomSpinnerAdapter(RegistrationScreen.this,R.layout.spinner_dropdown,countries));
progressBar.dismiss();
Log.e("Im in onPostExecute", "");
super.onPostExecute(result);
}
}
During onCreate(), I'm downloading resources from the web, which takes time. I'd like to display a message on the screen to advise the user. I tried toast, but nothing shows up. Is there another way to print something to the screen?
i think onCreate() work like a constructor for a class and you can not load any visual when it is not finished yet.
so i advice you to use another activity with your message and then call your activity in it.
You have to create a splash screen , that's the way it's called.
It's a mediator Activity that is handling such actions.
Example:
public class SplashScreen extends BaseActivity {
public ProgressDialog ProgressBar = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
HideTitle();
setContentView(R.layout.splash);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
if (!IsConnected()) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
finish();
}
}, 4000);
} else {
ProgressBar = ProgressDialog.show(this, "", "Loading...", false, false);
SplashScreenDelay splashScreenDelay = new SplashScreenDelay(this, this);
splashScreenDelay.execute(10);
}
}
here is the class that does the loading and after that sends to the main
public class SplashScreenDelay extends AsyncTask<Integer, Integer, List<RssItem>> {
private Context _context;
private SplashScreen _activity;
public SplashScreenDelay(SplashScreen activity, Context context) {
_context = context;
_activity = activity;
}
#Override
protected List<RssItem> doInBackground(Integer... params) {
return RssParsingService.getListOfItems();
}
#Override
protected void onPostExecute(List<RssItem> result) {
Intent intent = new Intent(_context, Viewport.class);
_context.startActivity(intent);
if (_activity.ProgressBar != null) {
_activity.ProgressBar.dismiss();
}
}
}