下面列出了android.view.View#getWindowVisibility ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* @return true if the given view is visible to user, false otherwise. The logic is leveraged from
* {@link View#isVisibleToUser()}.
*/
private static boolean isVisibleToUser(View view) {
if (view.getWindowVisibility() != View.VISIBLE) {
return false;
}
Object current = view;
while (current instanceof View) {
final View currentView = (View) current;
if (currentView.getAlpha() <= 0 || currentView.getVisibility() != View.VISIBLE) {
return false;
}
current = currentView.getParent();
}
return view.getGlobalVisibleRect(sDummyRect);
}
@SuppressLint("NewApi")
public static boolean isViewSelfVisible(View view) {
if (view == null || view.getWindowVisibility() == View.GONE) {
return false;
}
if (WindowHelper.isDecorView(view.getClass())) {
return true;
}
if (view.getWidth() <= 0 || view.getHeight() <= 0 || view.getAlpha() <= 0.0f || !view.getLocalVisibleRect(new Rect())) {
return false;
}
if ((view.getVisibility() == View.VISIBLE || view.getAnimation() == null || !view.getAnimation().getFillAfter()) && view.getVisibility() != View.VISIBLE) {
return false;
}
return true;
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void clearInputMethodManagerLeak() {
try {
Object lock = mHField.get(inputMethodManager);
// This is highly dependent on the InputMethodManager implementation.
synchronized (lock) {
View servedView = (View) mServedViewField.get(inputMethodManager);
if (servedView != null) {
boolean servedViewAttached = servedView.getWindowVisibility() != View.GONE;
if (servedViewAttached) {
// The view held by the IMM was replaced without a global focus change. Let's make
// sure we get notified when that view detaches.
// Avoid double registration.
servedView.removeOnAttachStateChangeListener(this);
servedView.addOnAttachStateChangeListener(this);
} else {
// servedView is not attached. InputMethodManager is being stupid!
Activity activity = extractActivity(servedView.getContext());
if (activity == null || activity.getWindow() == null) {
// Unlikely case. Let's finish the input anyways.
finishInputLockedMethod.invoke(inputMethodManager);
} else {
View decorView = activity.getWindow().peekDecorView();
boolean windowAttached = decorView.getWindowVisibility() != View.GONE;
if (!windowAttached) {
finishInputLockedMethod.invoke(inputMethodManager);
} else {
decorView.requestFocusFromTouch();
}
}
}
}
}
} catch (IllegalAccessException | InvocationTargetException unexpected) {
Log.e("IMMLeaks", "Unexpected reflection exception", unexpected);
}
}
@TargetApi(Build.VERSION_CODES.KITKAT)
private void clearInputMethodManagerLeak() {
try {
Object lock = mHField.get(inputMethodManager);
// This is highly dependent on the InputMethodManager implementation.
synchronized (lock) {
View servedView = (View) mServedViewField.get(inputMethodManager);
if (servedView != null) {
boolean servedViewAttached = servedView.getWindowVisibility() != View.GONE;
if (servedViewAttached) {
// The view held by the IMM was replaced without a global focus change. Let's make
// sure we get notified when that view detaches.
// Avoid double registration.
servedView.removeOnAttachStateChangeListener(this);
servedView.addOnAttachStateChangeListener(this);
} else {
// servedView is not attached. InputMethodManager is being stupid!
Activity activity = extractActivity(servedView.getContext());
if (activity == null || activity.getWindow() == null) {
// Unlikely case. Let's finish the input anyways.
finishInputLockedMethod.invoke(inputMethodManager);
} else {
View decorView = activity.getWindow().peekDecorView();
boolean windowAttached = decorView.getWindowVisibility() != View.GONE;
if (!windowAttached) {
finishInputLockedMethod.invoke(inputMethodManager);
} else {
decorView.requestFocusFromTouch();
}
}
}
}
}
} catch (IllegalAccessException | InvocationTargetException unexpected) {
Log.e("IMMLeaks", "Unexpected reflection exception", unexpected);
}
}
/**
* 判断一个View是否在当前的屏幕中可见(肉眼真实可见)
*
* @return 返回true则可见
*/
public static boolean isVisibleOnScreen(View view) {
if (view == null) {
return false;
}
return view.getWindowVisibility() == View.VISIBLE && view.getVisibility() == View.VISIBLE && view.isShown();
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void clearInputMethodManagerLeak() {
try {
Object lock = mHField.get(inputMethodManager);
// This is highly dependent on the InputMethodManager implementation.
synchronized (lock) {
View servedView = (View) mServedViewField.get(inputMethodManager);
if (servedView != null) {
boolean servedViewAttached = servedView.getWindowVisibility() != View.GONE;
if (servedViewAttached) {
// The view held by the IMM was replaced without a global focus change. Let's make
// sure we get notified when that view detaches.
// Avoid double registration.
servedView.removeOnAttachStateChangeListener(this);
servedView.addOnAttachStateChangeListener(this);
} else {
// servedView is not attached. InputMethodManager is being stupid!
Activity activity = extractActivity(servedView.getContext());
if (activity == null || activity.getWindow() == null) {
// Unlikely case. Let's finish the input anyways.
finishInputLockedMethod.invoke(inputMethodManager);
} else {
View decorView = activity.getWindow().peekDecorView();
boolean windowAttached = decorView.getWindowVisibility() != View.GONE;
if (!windowAttached) {
finishInputLockedMethod.invoke(inputMethodManager);
} else {
decorView.requestFocusFromTouch();
}
}
}
}
}
} catch (IllegalAccessException | InvocationTargetException unexpected) {
Log.e("IMMLeaks", "Unexpected reflection exception", unexpected);
}
}
@Override
public List<RootViewInfo> call() throws Exception {
mRootViews.clear();
if (AppStateManager.getInstance().isInBackground()) {
return mRootViews;
}
Activity activity = AppStateManager.getInstance().getForegroundActivity();
if (activity != null) {
JSONObject object = AopUtil.buildTitleAndScreenName(activity);
VisualUtil.mergeRnScreenNameAndTitle(object);
String screenName = object.optString(AopConstants.SCREEN_NAME);
String activityTitle = object.optString(AopConstants.TITLE);
final Window window = activity.getWindow();
final View rootView = window.getDecorView().getRootView();
final RootViewInfo info = new RootViewInfo(screenName, activityTitle, rootView);
final View[] views = WindowHelper.getSortedWindowViews();
Bitmap bitmap = null;
if (views != null && views.length > 0) {
bitmap = mergeViewLayers(views, info);
for (View view : views) {
if (view.getWindowVisibility() != View.VISIBLE || view.getVisibility() != View.VISIBLE
|| view.getWidth() == 0 || view.getHeight() == 0
|| TextUtils.equals(WindowHelper.getWindowPrefix(view), WindowHelper.getMainWindowPrefix()))
continue;
RootViewInfo subInfo = new RootViewInfo(screenName, activityTitle, view.getRootView());
scaleBitmap(subInfo, bitmap);
mRootViews.add(subInfo);
}
}
if (mRootViews.size() == 0) {
scaleBitmap(info, bitmap);
mRootViews.add(info);
}
}
return mRootViews;
}
public static boolean isWindowNeedTraverse(View root, String prefix, boolean skipOtherActivity) {
if (root.hashCode() == AppStateManager.getInstance().getCurrentRootWindowsHashCode()) {
return true;
}
if (root instanceof ViewGroup) {
if (!skipOtherActivity) {
return true;
}
if (!(root.getWindowVisibility() == View.GONE || root.getVisibility() != View.VISIBLE || TextUtils.equals(prefix, WindowHelper.getMainWindowPrefix()) || root.getWidth() == 0 || root.getHeight() == 0)) {
return true;
}
}
return false;
}
/**
* 遍历 ViewTree
*/
public void traverseViewTree() {
if (mDecorViewRef == null || mDecorViewRef.get() == null) {
return;
}
View view = mDecorViewRef.get();
if (view instanceof ViewGroup) {
if (view.getWindowVisibility() != GONE && view.getWidth() != 0 && view.getHeight() != 0 && view.getVisibility() == VISIBLE) {
Log.e(TAG, "traverseViewTree");
traverseView(mDecorViewRef.get());
//遍历完后,可以处理 Frg 浏览页面事件
handleFrgs();
}
}
}
private void clearInputMethodManagerLeak() {
try {
Object lock = mHField.get(inputMethodManager);
// This is highly dependent on the InputMethodManager implementation.
synchronized (lock) {
View servedView = (View) mServedViewField.get(inputMethodManager);
if (servedView != null) {
boolean servedViewAttached = servedView.getWindowVisibility() != View.GONE;
if (servedViewAttached) {
// The view held by the IMM was replaced without a global focus change. Let's make
// sure we get notified when that view detaches.
// Avoid double registration.
servedView.removeOnAttachStateChangeListener(this);
servedView.addOnAttachStateChangeListener(this);
} else {
// servedView is not attached. InputMethodManager is being stupid!
Activity activity = extractActivity(servedView.getContext());
if (activity == null || activity.getWindow() == null) {
// Unlikely case. Let's finish the input anyways.
finishInputLockedMethod.invoke(inputMethodManager);
} else {
View decorView = activity.getWindow().peekDecorView();
boolean windowAttached = decorView.getWindowVisibility() != View.GONE;
if (!windowAttached) {
finishInputLockedMethod.invoke(inputMethodManager);
} else {
decorView.requestFocusFromTouch();
}
}
}
}
}
} catch (Exception unexpected) {
Log.e("IMMLeaks", "Unexpected reflection exception", unexpected);
}
}