【问题标题】:WindowManager.addView BadTokenException on Orientation Change [duplicate]方向更改时的 WindowManager.addView BadTokenException [重复]
【发布时间】:2014-05-14 13:11:23
【问题描述】:

每次用户下拉以刷新显示的列表视图时,我都会尝试用 TextView 覆盖操作栏(与 Gmail 应用程序或 reddit 同步应用程序完全一样)。我正在使用 SwipeRefreshLayout 进行刷新,但我想这无关紧要。我有一个包含 TextView 并使用 WindowManager 将 textView 附加到显示器的类 (HeaderTransformer)。 HeaderTransformer 类的实例是从片段中调用的(其中包含要刷新的 SwipeRefreshLayout 和 ListView)。在第一次创建片段时,TextView 覆盖完美地工作。但是,如果我旋转屏幕或以某种方式重新创建片段,WindowManager 不会附加 TextView 并引发 BadTokenException。

这里有一些代码:

片段代码:

private HeaderTransformer ht;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {
   // Inflate the layout for this fragment
   View view =  inflater.inflate(R.layout.fragment_misc, container,     false);
   View refresh_header = getActivity().getLayoutInflater().inflate(R.layout.swipe_refresh_header_layout, null);
   ht = new HeaderTransformer(getActivity(), refresh_header);
}
@Override
public void onResume() {
    super.onResume();
    getActivity().runOnUiThread(new Runnable(){
       @Override
       public void run() {
       if(!getActivity().isFinishing())
               ht.addHeaderViewToActivity(getActivity());
       }
       });
}

HeaderTransformer.java

public class HeaderTransformer {
    private View mHeaderView;
    private TextView mMainTextView;
    private Context mContext;
    public HeaderTransformer(Context context, View headerView) {
        mHeaderView = headerView;
        mContext = context;
        mMainTextView = (TextView) headerView.findViewById(R.id.ptr_text);
    }

    public void onReset() {
        mMainTextView.setVisibility(View.VISIBLE);
        mMainTextView.setText(R.string.pull_to_refresh_label);
    }

    public void onRefreshStarted() {
        mMainTextView.setText(R.string.refreshing_label);
    }

    public void addHeaderViewToActivity(Activity mActivity) {

        Rect mRect = new Rect();
        // Get the Display Rect of the Decor View
           mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(mRect);

        // Honour the requested layout params
        int width = WindowManager.LayoutParams.MATCH_PARENT;
        int height = WindowManager.LayoutParams.WRAP_CONTENT;
        ViewGroup.LayoutParams requestedLp = mHeaderView.getLayoutParams();
        if (requestedLp != null) {
            width = requestedLp.width;
            height = requestedLp.height;
        }

        // Create LayoutParams for adding the View as a panel
        WindowManager.LayoutParams wlp = new WindowManager.LayoutParams(width, height,
            WindowManager.LayoutParams.TYPE_APPLICATION_PANEL,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
            PixelFormat.TRANSLUCENT);
        wlp.x = 0;
        wlp.y = mRect.top;
        wlp.gravity = Gravity.TOP | Gravity.LEFT;
        // Workaround for Issue #182
        mHeaderView.setTag(wlp);
        try{
            mActivity.getWindowManager().addView(mHeaderView, wlp);
        }
        catch(Exception e){
            e.printStackTrace();
        }
}

这是堆栈跟踪:

05-14 00:09:03.286: W/System.err(18190): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running? 
05-14 00:09:03.286: W/System.err(18190): at android.view.ViewRootImpl.setView(ViewRootImpl.java)
05-14 00:09:03.286: W/System.err(18190): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java) 
05-14 00:09:03.286: W/System.err(18190): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java) 
05-14 00:09:03.286: W/System.err(18190): at com.faisalalqadi.resume.util.HeaderTransformer.addHeaderViewToActivity(HeaderTransformer.java:72) 
05-14 00:09:03.286: W/System.err(18190):at com.faisalalqadi.resume.fragment.MiscellaneousFragment$3.run(MiscellaneousFragment.java:260) 
05-14 00:09:03.286: W/System.err(18190): at android.app.Activity.runOnUiThread(Activity.java) 
05-14 00:09:03.286: W/System.err(18190): at com.faisalalqadi.resume.fragment.MiscellaneousFragment.onResume(MiscellaneousFragment.java:256) 
05-14 00:09:03.296: W/System.err(18190): at android.support.v4.app.Fragment.performResume(Fragment.java:1543) 
05-14 00:09:03.296: W/System.err(18190): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:974) 
05-14 00:09:03.296: W/System.err(18190): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1115) 
05-14 00:09:03.296: W/System.err(18190): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1097) 
05-14 00:09:03.296: W/System.err(18190): at android.support.v4.app.FragmentManagerImpl.dispatchResume(FragmentManager.java:1905) 
05-14 00:09:03.296: W/System.err(18190): at android.support.v4.app.FragmentActivity.onResumeFragments(FragmentActivity.java:466) 
05-14 00:09:03.296: W/System.err(18190): at android.support.v4.app.FragmentActivity.onPostResume(FragmentActivity.java:455) 
05-14 00:09:03.296: W/System.err(18190): at android.app.Activity.performResume(Activity.java) 
05-14 00:09:03.296: W/System.err(18190): at android.app.ActivityThread.performResumeActivity(ActivityThread.java) 
05-14 00:09:03.296: W/System.err(18190): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java) 
05-14 00:09:03.296: W/System.err(18190): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java) 
05-14 00:09:03.296: W/System.err(18190): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java) 
05-14 00:09:03.296: W/System.err(18190): at android.app.ActivityThread.access$900(ActivityThread.java) 
05-14 00:09:03.296: W/System.err(18190): at android.app.ActivityThread$H.handleMessage(ActivityThread.java) 
05-14 00:09:03.296: W/System.err(18190): at android.os.Handler.dispatchMessage(Handler.java) 
05-14 00:09:03.296: W/System.err(18190): at android.os.Looper.loop(Looper.java) 
05-14 00:09:03.296: W/System.err(18190): at android.app.ActivityThread.main(ActivityThread.java) 
05-14 00:09:03.296: W/System.err(18190): at java.lang.reflect.Method.invokeNative(Native Method) 
05-14 00:09:03.296: W/System.err(18190): at java.lang.reflect.Method.invoke(Method.java) 
05-14 00:09:03.296: W/System.err(18190): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)

我一直在寻找任何可以表明任何异常的东西。我看过的所有资源都说将 getApplicationContext() 替换为 Activity.this。我认为错误的根源是 HeaderTransformer 持有对在方向更改时被破坏/删除的活动/视图的引用。我尝试删除对 HeaderTransformer 实例的实例所持有的视图或活动的任何引用(并将所有函数更改为将 mHeaderView 作为参数(而不是局部变量)传递。我仍然得到 BadTokenException。

有人知道是什么原因造成的吗?

【问题讨论】:

标签: java android android-fragments android-windowmanager


【解决方案1】:

所以保存您的实例,并在旋转屏幕时获取您保存的实例并传递给转换类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-21
    • 2019-06-06
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    相关资源
    最近更新 更多