Goal: Have a ProgressDialog which shows "Loading..." until next Activity is completely loaded and shown on screen.
Tried with ProgressDialog context and activity set to originating Activity. Also tried with getApplicationContext() and getParentContext(). Exceptions on the last two approaches. Need to do this as destination Activity is slow to render due to non-simple Layout file. (Cannot fix that right now due to organizational issues.) Turns out the destination Activity takes 1-2 seconds to OnCreate and then screen goes black for up to 5+ seconds then it paints. The rendering is just slow. Did review with Hierarchy Viewer and see lots of red balls but can't fix now.
Read up on some related but haven't found a fix. E.g. What's the difference between the various methods to get a Context?
E.g. both of these crash. Using the "this" of source Activity doesn't work either.
// Context parentContext = this.getParent().getBaseContext();
Context parentContext = this.getApplicationContext();
ProgressDialogMenuable theProgressDialog = new ProgressDialogMenuable(parentContext,this);
theProgressDialog.setTitle("yeeha");
theProgressDialog.setMessage("weewah");
theProgressDialog.setIndeterminate(true);
theProgressDialog.setCancelable(true);
theProgressDialog.show();
Also, oddly, nothing happens when I do this:
theProgressDialog.show();
ActivityHelper.changeActivity(this, v, InsMyHoldingsActivity.class, extraMap, -1, -1);
User clicks button to show next activity but the ProgressDialog conflicts with the Activity launch and nothing actually happens other than the button becoming yellow ontouch. Button below works. removing ProgressDialog creation and it works. No console messages logged. A little offputting to the developer for sure.
You can show a progress dialog like this -
Define this
private ProgressDialog pd = null;
in your activity class
Put this in your onCreate (Dont setContentView directly here)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.pd = ProgressDialog.show(this, "Fancy App",
"Loading...Please wait...", true, false);
// Start a new thread that will download all the data
new IAmABackgroundTask().execute();
}
// Background heavy lifting
class IAmABackgroundTask extends
AsyncTask<String, Integer, Boolean> {
#Override
protected void onPreExecute() {
// showDialog(AUTHORIZING_DIALOG);
}
#Override
protected void onPostExecute(Boolean result) {
// Pass the result data back to the main activity
ActivityName.this.data = result;
if (ActivityName.this.pd != null) {
ActivityName.this.pd.dismiss();
}
setContentView(R.layout.main);
}
#Override
protected Boolean doInBackground(String... params) {
//Do all your slow tasks here but dont set anything on UI
//ALL ui activities on the main thread
return true;
}
}
Also go through this :http://developer.android.com/training/improving-layouts/index.html for optimizing layout performance.
Also Use Traceview to look for bottlenecks
There is two ways to
First approach To use Async Task
If you are doing heavy tasks eg loading data from server or parsing xml in that case use AsynTask<> If you want to call ActivityB from ActivityA then
*step-1*create a AsyncTask class. write all background tasks inside doBackground() method and after completion of task you want to call an activity that code write inside onPostExecute() post execute method
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.view.View;
public class LoadingDataFromServer extends AsyncTask {
Context currentContext = null;
boolean isCancelled = false;
public LoadingDataFromServer(Context context) {
currentContext = context;
}
#Override
protected void onPreExecute() {
if (DashboardActivity.progressBarLayout != null) {
DashboardActivity.progressBarLayout.setVisibility(View.VISIBLE);
// Log.i(TAG,".....Now make progress bar visible.....");
}
super.onPreExecute();
}
#Override
protected Object doInBackground(Object... params) {
// do background processing
try {
// do background tasks eg sever communication
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Object result) {
// TODO Auto-generated method stub
// progressDialog.dismiss();
// call second Activity
Intent i = new Intent(currentContext, com.ActvityB.class);
super.onPostExecute(result);
}
#Override
protected void onCancelled() {
// TODO Auto-generated method stub
isCancelled = true;
super.onCancelled();
}
}
step-2 In the activity fro where you want to jump to new activity (eg in ActivityA) call the execute() of AsynTask
new LoadingDataFromServer(context).execute(null);
Second approach
First show progress dialog.
create a thread to do all background tasks. when the thread completes the task then cancel the progress dialog and call the next activity
or
when thread complets the task then call next activity pass this object (progress dialog) and inside that new activity dismiss this dialog.
Here is my code that can help.
In this, I'm only posting the first method of AsyncTask i.e onPreExecute.
User_AsyncTask extends AsyncTask:
public class User_AsyncTask extends AsyncTask<String, String, String>
{
String response = "";
#Override
protected void onPreExecute()
{
try
{
if (progressDialog != null)
progressDialog.cancel();
}
catch (Exception e)
{
}
progressDialog = ProgressDialog.show(DisplayDetails.this, "", "Please wait...", true, true);
progressDialog.setCancelable(false);
progressDialog.show();
}
Related
I've an Activity that contains a lot of data and elements.
When it has too information, the activity wait in white for be shown, that is not I want, I actually want to show a activity while it's loading the data.
So, How can I to know when my activity it's fully created?
My intention is to launch in a second thread the activity across the waiting activity.
You should load that data asynchronously, in another thread if it takes that much time to load. Launch another thread (by using an AsyncTask for example of plain Java Threads), load the data and show some loading-View on the Activity that notifies the user that something is happening in the background.
You can use AsyncTask and can show progress dialog till the data is loaded.
private class FetchRSSFeeds extends AsyncTask<String, Void, Boolean> {
private ProgressDialog dialog = new ProgressDialog(HomeActivity.this);
protected void onPreExecute() {
this.dialog.setMessage(getResources().getString(
R.string.Loading_String));
this.dialog.show();
}
protected Boolean doInBackground(final String... args) {
try {
// Fetch the data from URL
// do background process
return true;
} catch (Exception e) {
Log.e("tag", "error", e);
return false;
}
}
#Override
protected void onPostExecute(final Boolean success) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if (success) {
// Setting data to list adaptar
setListData();
}
}
This method called after on create in activity
#Override
public void onStart() {
super.onStart();
}
my data is load from the internet, so I use the AsynTask(). execute() method to open a progressDialog first, then load the data in the background. it works, however, sometimes it takes too long to load the data so I want to cancel loading, and here is the problem: when I click back button the dialog dismiss but after it finish loading at the background, it start to do whatever it supposed to do after loading, e.g. start a new intent.
is there any way I can cancel the loading properly???
new GridViewAsyncTask().execute();
public class GridViewAsyncTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog myDialog;
#Override
protected void onPreExecute() {
// show your dialog here
myDialog = ProgressDialog.show(ScrollingTab.this, "Checking data",
"Please wait...", true, true);
}
#Override
protected Void doInBackground(Void... params) {
// update your DB - it will run in a different thread
loadingData();
return null;
}
#Override
protected void onPostExecute(Void result) {
// hide your dialog here
myDialog.dismiss();
}
Call mAsycntask.cancel(); when you want to stop the task.
Then
#Override
protected Void doInBackground(Void... params) {
// update your DB - it will run in a different thread
/* load data */
....
if (isCancelled())
return;
/* continue loading data. */
return null;
}
Documentation:
http://developer.android.com/reference/android/os/AsyncTask.html#isCancelled()
Declare your AsyncTask like asyncTask = new GridViewAsyncTask();
Then execute it as you did it before (asyncTask.execute();) and to cancel it:
asyncTask.cancel();
Add the onCanceled method to your AsyncTask class and override it. Perhaps to show a Log or something else!
#Override
protected Void onCancelled () {
// Your Log here. Will be triggered when you hit cancell.
}
I'm having a minor problem and I don't know how to do it.
I created a app, that pulls information through an xml web service.
The data get's parsed and inserted into a local sqlite database.
Everything works so far.
Due to the size of the data (that varies based on the pulled information) I intended to insert a loading screen with a progressbar and a spinner to notify the user that actions are taken.
Well let's say it, that it is planed to work this way.
My Problem is, that it is displayed, as soon as the work is done, not bevor.
This is how I've done it:
Handler phHandle = new Handler(){
#Override
public void handleMessage(Message msg){
int progress = msg.arg1;
pb.setProgress(progress);
}
};
class firstInitHandler implements Runnable{
private Handler phHandle;
public void setHandle(Handler h){
this.phHandle = h;
}
public void run(){
try {
firstInit i = new firstInit();
i.doInit(this.phHandle);
if(i.isResult())
i.doParse();
if(i.isData()){
i.doTasks();
i.doEquipment();
i.doUser();
i.doCompany();
i.doForms();
i.doSysconfig();
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
}
firstInitHandler h = new firstInitHandler();
h.setHandle(phHandle);
h.run();
This is part of a method.
Well it works so far.
The thread for processing the information is visible in task manager in the sdk.
I can also see the status messages on logcat that are created while the debug system works.
But the screen stays blank and only is displayed as soon as the task is done.
I'm a little bit confused and don't know where to start to have the waiting screen work.
I would welcome any help.
Chris
You can use AsyncTask fot this to work smoothly....
Inside your activity define the AsyncTask ....
then you can call the AsyncTask from onclick or inside onCreate in this way
new loading().execute();
The AsyncTask class will be as below.
The basic concept is to initialize the progress dialog in
onPerExecute().
Do the heavy stuff (non UI ) like parsing and all in
DoInBackground().
Then dismiss the dialog in onPostExecute().
you cannot do the UI changes in DoinBackGround, but you can do that
in OnPre / OnPostExecute().
the class is as follows.
private class loading extends AsyncTask'<'String, Integer, Boolean>
{
ProgressDialog dialog ;
#Override
protected void onPostExecute(Boolean result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if(result==true)
{
dialog.dismiss();
}
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
dialog = new ProgressDialog(current.this);
dialog.setMessage("Loading...");
dialog.show();
}
#Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
#Override
protected Boolean doInBackground(String... params) {
// TODO Auto-generated method stub
try {
firstInit i = new firstInit();
i.doInit(this.phHandle);
if(i.isResult())
i.doParse();
if(i.isData()){
i.doTasks();
i.doEquipment();
i.doUser();
i.doCompany();
i.doForms();
i.doSysconfig();
}
} catch (NullPointerException e)
{
e.printStackTrace();
return false;
}
return true;
}
}
Have you tried looking at the Android Developers resources?
Here is the Dialog tutorial. A progress dialog example is shown on this page, or you could hop to the specific progress dialog section where it shows all the possible commands, usages, etc.
Hope this is what you need.
I have an activity 'Activity1' and also another activity named 'Activity2'. The 'Activity2' is loaded upon clicking a button in 'Activity1'. I wanted to display the progress dialog until the new activity is loaded . Can you please show me the code to do this
Display the progress dialog in Activity2's onCreate method, then do all the time-consuming loading in an AsyncTask. In the AsyncTask's onPostExecute() method, dismiss the progress dialog.
There is two ways to
First approach To use Async Task
If you are doing heavy tasks eg loading data from server or parsing xml in that case use AsynTask<>
If you want to call ActivityB from ActivityA then
*step-1*create a AsyncTask class. write all background tasks inside doBackground() method and after completion of task you want to call an activity that code write inside onPostExecute() post execute method
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.view.View;
public class LoadingDataFromServer extends AsyncTask {
Context currentContext = null;
boolean isCancelled = false;
public LoadingDataFromServer(Context context) {
currentContext = context;
}
#Override
protected void onPreExecute() {
if (DashboardActivity.progressBarLayout != null) {
DashboardActivity.progressBarLayout.setVisibility(View.VISIBLE);
// Log.i(TAG,".....Now make progress bar visible.....");
}
super.onPreExecute();
}
#Override
protected Object doInBackground(Object... params) {
// do background processing
try {
// do background tasks eg sever communication
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Object result) {
// TODO Auto-generated method stub
// progressDialog.dismiss();
// call second Activity
Intent i = new Intent(currentContext, com.ActvityB.class);
super.onPostExecute(result);
}
#Override
protected void onCancelled() {
// TODO Auto-generated method stub
isCancelled = true;
super.onCancelled();
}
}
step-2 In the activity fro where you want to jump to new activity (eg in ActivityA) call the execute() of AsynTask
new LoadingDataFromServer(context).execute(null);
Second approach
First show progress dialog.
create a thread to do all background tasks. when the thread completes
the task then cancel the progress dialog and call the next activity
or
when thread complets the task then call next activity pass this
object (progress dialog) and inside that new activity dismiss this
dialog.
yes by using AsynTask<> you can get your result
in OnPreExecute Show your Progress dialog,in OndoInBackground run your activity,in onPostExecute remove your dialog
get the idea Get Concept
The other answers (using AsynTask) are correct, but the question you need to figure out is what is causing your delay. Is it something happening on the back end of Activity1 or something happening on the front end Activity2. If you're doing some processing before starting Activity2 then follow the advice of Last Warrior or Ted Hopp... if you have some lengthy loading process in Activity2 then you'll need to initiate the progress dialog as the first thing that happens onCreate of Activity2 and then move whatever is taking up processing resources off into an AsynTask (or just another thread) there.
I guess in the unlikely event that both A1 and A2 are requiring extra time on the end and front of each respectively, you'll need to open and close a progress dialog... I don't think there's a way to keep one open in the foreground as you move from one activity to the other.
you can do it through AsyncTAsk. Which code taking time for executing just put that into
doInBackground()
override method of asyncTask and
startActivity(intent) ----just put into onPostExcute()
protected class InitTask extends AsyncTask<Context, Integer, Integer> {
#Override protected Integer onPreExcute( Context... params ) {
//assign progressbar here
}
#Override protected Integer doInBackground( Context... params ) {
//do all the stuffs here
return super.doInBackground( params )
} #Override protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
//update progress bar
}
#Override protected void onPostExecute( Integer result ) {
super.onPostExecute(result);
//start activity here
}
}
I'm using following code to fill a custom ListPreference dialog. Since the fill procedure takes a lot of time i want to show a progress dialog during the fill procedure.
My problem is that filler.execute() does not block onPrepareDialogBuilder and functions goes till the end before values are filled causing an exception... Any idea?
#Override
protected void onPrepareDialogBuilder(Builder builder) {
// Load data
if (this.getEntries()==null) {
FillerTask filler = new FillerTask();
filler.execute();
}
Log.d(TAG, "Filler finished");
super.onPrepareDialogBuilder(builder);
}
Here is Filltertask code, basically he looks for every activity with a MAIN Intent filling a list:
private class FillerTask extends AsyncTask<Void, Void, String[][]> {
private ProgressDialog dialog;
#Override
protected void onPreExecute() {
Log.d(TAG, "Dismiss dialog");
dialog = ProgressDialog.show(MyListPreference.this.getContext(), "", "Doing stuff...", true);
}
#Override
protected String[][] doInBackground(Void... params) {
return fill();
}
public String[][] fill() {
Log.d(TAG, "Fill started");
CREATE LISTS...
// Done
Log.d(TAG, "Fill done");
String[][] result = new String[][] {entryNames, entryValues};
return result;
}
#Override
protected void onPostExecute(String[][] result) {
Log.d(TAG, "Post execute");
MyListPreference.this.setEntries(result[0]);
MyListPreference.this.setEntryValues(result[1]);
dialog.dismiss();
}
}
My problem is that filler.execute() does not block onPrepareDialogBuilder and functions goes till the end before values are filled causing an exception... Any idea?
That is the entire point behind an AsyncTask. The "Async" in AsyncTask means asynchronous.
Use your AsyncTask to get your data. Then, in onPostExecute(), display the dialog.
Found the solution, best way to do this is override the onClick method and let the AsyncTask postExecute call the "super()", so click is not passed until content is loaded and during load progress bar is correctly displayed.
asyntask doesn't lock main thread, it just drops a message to message queue of main thread