I'm currently trying to implement a custom loading dialog, However when I try to inflate my layout in the PreExecute of an AsyncTask the app crashes with a BadTokenException. I haven't been able to figure out whats causing this problem. The error is specifically at the popupWindow.showAtLocation(view,Gravity.CENTER, 0, 0); line.
The ProgressDialog class:
public class ProgressDialog {
private Context mContext;
private PopupWindow popupWindow;
private TextView details;
private TextView loadingText;
private View view;
public ProgressDialog(Context c, View view) {
this.mContext = c;
this.view = view;
}
public void show(String message){ //copied this off an answer to a different question
// inflate the layout of the popup window
LayoutInflater inflater = (LayoutInflater)
mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
View popupView = inflater.inflate(R.layout.custom_loading, null);
// create the popup window
int width = LinearLayout.LayoutParams.WRAP_CONTENT;
int height = LinearLayout.LayoutParams.WRAP_CONTENT;
boolean focusable = true; // lets taps outside the popup also dismiss it
popupWindow = new PopupWindow(popupView, width, height, focusable);
popupWindow.setElevation(20);
popupWindow.setBackgroundDrawable(ContextCompat.getDrawable(mContext,R.drawable.transparent_back));
// show the popup window
// which view you pass in doesn't matter, it is only used for the window token
loadingText = popupView.findViewById(R.id.dialogTitle);
loadingText.setText(R.string.loadingString);
details = popupView.findViewById(R.id.dialogInfo);
details.setText(message);
popupWindow.showAtLocation(view,Gravity.CENTER, 0, 0);
}
public void dismiss(){
popupWindow.dismiss();
}
}
The Activity:
private ProgressDialog prg;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_splash);
AdView mAdView = findViewById(R.id.adView);
prg = new ProgressDialog(this, mAdView);
//Do some stuff
}
public void ReadSongs()
{
AsyncTask<Void,Void,Void> task = new AsyncTask<Void, Void, Void>(){
@Override
protected void onPreExecute(){
prg.show("Some Message");
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... voids){
//Do Stuff
return null;
}
@Override
protected void onPostExecute(Void aVoid){
prg.dismiss();
startMainActivity();
super.onPostExecute(aVoid);
}
}.execute();
}
The LogCat:
PID: 10363 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myproject/com.example.myproject.SpotifySongReadAct}: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:907)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:387)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:95)
at android.widget.PopupWindow.invokePopup(PopupWindow.java:1577)
at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1343)
at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1309)
at utility.ProgressDialog.show(ProgressDialog.java:46)
at com.barbecu.switcheroo.SpotifySongReadAct$1.onPreExecute(SpotifySongReadAct.java:50)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:708)
at android.os.AsyncTask.execute(AsyncTask.java:655)
at com.barbecu.switcheroo.SpotifySongReadAct.ReadSongs(SpotifySongReadAct.java:100)
at com.barbecu.switcheroo.SpotifySongReadAct.onCreate(SpotifySongReadAct.java:114)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
.showAtLocation(view,Gravity.CENTER, 0, 0)and you're not specifying a container ininflate()showAtLocationmethod requires the first argument (theView) to be attached to the screen already. If you check itswindowTokenit will benull, and if you want popup to show it must not be null. I see by looking at stacktrace that you callReadSongs()fromonCreatemethod. It is too early. You must move it toActivity#onAttachedToWindow()at least.