ViewRootImpl的mThread什么时候赋的值?

上篇文章:子线程更新主线程的View抛出异常全过程,ViewRootImpl的checkThread方法中,通过mThread来判断,要更新View的线程和创建View的线程,是不是同一个,如果不是就抛出异常。

    void checkThread() {
        if (mThread != Thread.currentThread()) {
            throw new CalledFromWrongThreadException(
                    "Only the original thread that created a view hierarchy can touch its views.");
        }
    }

那么这个mThread是什么时候被赋值的了?

本文目录

  • ViewRootImpl的mThread什么时候赋的值?
  • ViewRootImpl对象什么时候生成的?
  • 其他疑问

ViewRootImpl的mThread什么时候赋的值?

在ViewRootImpl对象生成的时候,也就是ViewRootImpl的构造函数里面赋的值。
/frameworks/base/core/java/android/view/ViewRootImpl.java

public ViewRootImpl(Context context, Display display) {
        ......
        mThread = Thread.currentThread();
		......
}

在子线程中更新view的问题

ViewRootImpl对象什么时候生成的?

	//Activity.java
	void makeVisible() {
        if (!mWindowAdded) {
            ViewManager wm = getWindowManager();
            wm.addView(mDecor, getWindow().getAttributes());
            mWindowAdded = true;
        }
        mDecor.setVisibility(View.VISIBLE);
    }
	
	//getWindowManager返回了mWindowManager
    public WindowManager getWindowManager() {
        return mWindowManager;
    }

	 private WindowManager mWindowManager;

ViewManager是一个接口,WindowManager也是一个接口,WindowManager继承自ViewManager。如下:
/frameworks/base/core/java/android/view/ViewManager.java
/frameworks/base/core/java/android/view/WindowManager.java

public interface ViewManager//定义对View的增删改
{
    public void addView(View view, ViewGroup.LayoutParams params);
    public void updateViewLayout(View view, ViewGroup.LayoutParams params);
    public void removeView(View view);
}

public interface WindowManager extends ViewManager { //可见WindowManager也提供对View的增删改的接口方法
	......
}

WindowManager的具体实现类是WindowManagerImpl,我们看看WindowManagerImpl#addView()方法。

@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
    applyDefaultToken(params);
    mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,mContext.getUserId());
}

//mGlobal 是WindowManagerGlobal类的对象
public final class WindowManagerImpl implements WindowManager {
    private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
	......
}

接着看WindowManagerGlobal#addView()方法。
/frameworks/base/core/java/android/view/WindowManagerGlobal.java

public void addView(View view, ViewGroup.LayoutParams params,
        Display display, Window parentWindow, int userId) {
    ......
   
    ViewRootImpl root;
    View panelParentView = null;

    synchronized (mLock) {
        ...
        //创建ViewRootImpl对象
        root = new ViewRootImpl(view.getContext(), display);
		//设置View的布局属性
        view.setLayoutParams(wparams);
		//将相关信息保存到对应集合
        mViews.add(view);
        mRoots.add(root);
        mParams.add(wparams);

        try {
            root.setView(view, wparams, panelParentView, userId);//调用ViewRootImpl对象的setView方法(这里也是View绘制的根源)
        } catch (RuntimeException e) {
            ...
        }
    }
}

在WindowManagerGlobal#addView()方法里,我们看到了ViewRootImpl对象的初始化。

总结:
WindowManagerGlobal的addView()方法里面,生成了ViewRootImpl对象。
在子线程中更新view的问题
Window和WindowManager和ViewRootImpl

看到这里,继续追问:ViewRootImpl的初始化确定是在主线程吗?这个问题比较复杂,后面的文章,接着分析。

其他疑问

  • WindowManager与ViewRootImpl是什么关系?
    WindowManagerGlobal有存储ViewRootImpl的集合,mRoots。
    Window和WindowManager和ViewRootImpl

  • mRoots是干啥的?
    存储所有的ViewRootImpl。

  • Global为什么要保存ViewRootImpl?
    后面会需要查询。

  • 一个 Activity 有多少个 ViewRootImpl?
    ViewRootImpl 是实际管理 Window 中所有 View 的类,每个 Activity 中 ViewRootImpl 数量取决于调用mWindowManager.addView() 的次数。
    Framework篇 - 一文搞懂 Activity、View、Window、ViewRootImpl

你可能感兴趣的:(Handler,android,java,android,studio)