问题
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.
回答1:
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
回答2:
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.
回答3:
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();
}
来源:https://stackoverflow.com/questions/13017122/how-to-show-progressdialog-across-launching-a-new-activity