我有一个popUpWindow,如果用户仍处于当前活动状态,需要在几秒钟后显示。我实现了检查活动是否未完成/销毁然后显示弹出窗口,并且它适用于周末用户:)(从活动到活动慢慢点击)但在高压测试中(活动正在重新创建,完成,快速移动形式)活动到活动)给了我那个错误:
E / UncaughtException:android.view.WindowManager $ BadTokenException: 无法添加窗口 - 令牌null无效;是你的活动 运行? 在android.view.ViewRootImpl.setView(ViewRootImpl.java:598) 在 android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:341) 在android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85) 在android.widget.PopupWindow.invokePopup(PopupWindow.java:1279) 在android.widget.PopupWindow.showAtLocation(PopupWindow.java:1040) 在android.widget.PopupWindow.showAtLocation(PopupWindow.java:1003) 在com.guides4art.app.ImageSlider.RatePopUp $ 3.run(RatePopUp.java:86) 在android.os.Handler.handleCallback(Handler.java:743) 在android.os.Handler.dispatchMessage(Handler.java:95) 在android.os.Looper.loop(Looper.java:150) 在android.app.ActivityThread.main(ActivityThread.java:5546) at java.lang.reflect.Method.invoke(Native Method) 在 com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:794) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
代码:
private void showPopUpWindow(final Activity context){
popupWindow = new PopupWindow(context);
LinearLayout.LayoutParams layoutParams =new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
popupWindow.setHeight(layoutParams.height);
popupWindow.setWidth(layoutParams.width);
popupWindow.setOutsideTouchable(true);
popupWindow.setTouchable(true);
popupWindow.setFocusable(true);
popupWindow.setContentView(view);
ratingBar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
@Override
public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
if(context instanceof CarSale) {
((CarSale) context).saveRate((int) rating);
((CarSale) context).initRate();
title.setText(""+context.getString(R.string.thanksForRate));
}
else
Log.i("kamil","error");
}
});
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupWindow.dismiss();
}
});
if(!context.isFinishing() || !context.isDestroyed() )
activityView.post(new Runnable() {
@Override
public void run() {
popupWindow.showAtLocation(context.getWindow().getDecorView(), Gravity.CENTER,0,0);
}
});
}
//View Pager Class
@Override
public void onPageSelected(int position) {
if(viewPager !=null){
this.position=position;
if(position==carList.size()-1 && isRated() && showRateBar)
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
new RatePopUp(Cars.this,activityView);
showRateBar=false;
}
},5*SECOND);
//RatePopUp constructor
public RatePopUp(Activity context,View activityView){
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.rate_popup_layout, null);
this.activityView=activityView;
ratingBar = (RatingBar) view.findViewById(R.id.ratingPop);
title= (TextView)view.findViewById(R.id.rateTitle);
title.setText(context.getString(R.string.rate_exhibition));
closeButton = (Button)view.findViewById(R.id.close_button);
Typeface typeface =Typeface.createFromAsset(context.getAssets(),"fonts/fontawesome-webfont.ttf");
closeButton.setTypeface(typeface);
closeButton.setText(context.getString(R.string.exitIcon));
showPopUpWindow(context);
}
答案 0 :(得分:1)
试试这段代码:
new Handler().postDelayed(new Runnable(){
public void run() {
popupWindow.showAtLocation(context.getWindow().getDecorView(), Gravity.CENTER,0,0);
}
}, 200L);
而不是:
popupWindow.showAtLocation(context.getWindow().getDecorView(), Gravity.CENTER,0,0);
另外,请确保将ActivityName.this
作为上下文传递..而不是getApplicationContext
()
尝试使用以下代码替换runnable
中的showPopUpWindow()
代码:
runOnUiThread(new Runnable() {
@Override
public void run() {
if (!isFinishing()) {
popupWindow.showAtLocation(context.getWindow().getDecorView(), Gravity.CENTER, 0, 0);
}
}
});
答案 1 :(得分:0)
在使用弹出窗口时,应该有两种状态:
Activity 是活动的,即 Activity 没有被销毁并完成
如果活动被创建或者你传递的父视图附加到窗口 示例代码如下:
val decorView = ctx.window.decorView
decorView.post {
val posArr = IntArray(2)
anchorView.getLocationInWindow(posArr)
val yOffset = posArr[1] - anchorView.height + verticalOffset
if (isActivityAlive(ctx) && decorView.isAttachedToWindow) {
pop.showAtLocation(decorView, Gravity.TOP, 0, yOffset)
}
}
private fun isActivityAlive(ctx: Activity?): Boolean {
return ctx != null && !ctx.isDestroyed && !ctx.isFinishing
}
答案 2 :(得分:-1)
希望这会对你有帮助......
替换:
pwindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
使用:
new Handler().postDelayed(new Runnable(){
public void run() {
pwindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
}
}, 100L);
答案 3 :(得分:-1)
在我的研究中,您无法在没有活动的情况下调用弹出窗口。弹出窗口不能在弹出窗口或对话框中调用。