手记

Android -- onAttachedToWindow()

onAttachedToWindow在Activity生命周期中的位置

放大招:

onAttachedToWindow不能在onCreate中哟~

View view = getWindow().getDecorView();  
WindowManager.LayoutParams lp = (WindowManager.LayoutParams)view.getLayoutParams();  
lp.gravity = Gravity.CENTER;  
lp.width = (dm.widthPixels * 4) / 5;  
lp.height = (dm.widthPixels * 4) / 5;  
getWindowManager().updateViewLayout(view,lp);

放到onCreate中进行测试,结果在lp.gravity = Gravity.CENTER;这行报了空指针异常,所以view.getLayoutParams()获取的LayoutParams是空。

public final class ActivityThread {	  ......	
  final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {	
    ......	
    ActivityClientRecord r = performResumeActivity(token, clearHide);	
    if (r != null) {	
      final Activity a = r.activity;	
      ......	
      // If the window hasn't yet been added to the window manager,	      // and this guy didn't finish itself or start another activity,	      // then go ahead and add the window.	      boolean willBeVisible = !a.mStartedActivity;	
      if (!willBeVisible) {	
        try {	
          willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(	
              a.getActivityToken());	
        } catch (RemoteException e) {	
        }	
      }	
      if (r.window == null && !a.mFinished && willBeVisible) {	
        r.window = r.activity.getWindow();	
        View decor = r.window.getDecorView();	
        decor.setVisibility(View.INVISIBLE);	
        ViewManager wm = a.getWindowManager();	
        WindowManager.LayoutParams l = r.window.getAttributes();	
        a.mDecor = decor;	
        l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;	
        ......	
        if (a.mVisibleFromClient) {	
          a.mWindowAdded = true;	
          wm.addView(decor, l);	
        }	
      }	 
      ......	
    }	
    ......	
  }	
  ......	
}

原来在ActivityThread 执行handleResumeActivity时就会为PhoneWindow(r.activity.getWindow)中的DecorView设置LayoutParam ,并且通过源码发现 handleResumeActivity函数首先会执行performResumeActivity,此时会调用Activity的onResume()生命周期函数 ,这时问题就比较清晰了,看来只要在Activity的onResume生命周期后就能获取DecorView的LayoutParam,进而可以设置高度和宽度了。根据上面贴出的生命周期图,onResume()后面是onAttachedToWindow(),并且onAttachedToWindow只会调用一次,不会受用户操作行为影响。所以在onAttachedToWindow中进行窗口尺寸的修改再合适不过了。

干货

  • onAttachedToWindow运行在onResume之后;

  • DecorView的LayoutParams是在ActivityThread的handleResumeActivity中设置的,并且该函数会调用Activity的onResume生命周期,所以在onResume之后可以设置窗体尺寸;

原文链接:http://www.apkbus.com/blog-625968-58774.html

0人推荐
随时随地看视频
慕课网APP