
TextView mview = new TextView(context);
WindowManager mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams();
wmParams.type = WindowManager.LayoutParams.TYPE_TOAST;
wmParams.width = 800;
wmParams.height = 800;
mWindowManager.addView(mview, wmParams);

想要弄清楚View是怎么绘制的得先弄明白View是怎么创建出来的。我们先来看下View的创建流程。

悬浮窗添加流程:
从 WindowManager 到 WMS 的具体流程如下所示:

这里讲解一下AIDL交互的流程逻辑
WindowManager.updateViewLayout()解析
WindowManager.removeView()解析
Settings.canDrawOverlays(this)
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
//创建WindowManager
windowManager = (WindowManager)applicationContext.getSystemService(Context.WINDOW_SERVICE);
layoutParams = new WindowManager.LayoutParams();
layoutParams = new WindowManager.LayoutParams();
wmParams.type = WindowManager.LayoutParams.TYPE_TOAST;
wmParams.width = 800;
wmParams.height = 800;
mWindowManager.addView(mview, wmParams);
// 新建悬浮窗控件
View view = LayoutInflater.from(this).inflate(R.layout.float_window, null);
view.setOnTouchListener(new FloatingOnTouchListener());
// 将悬浮窗控件添加到WindowManager
windowManager.addView(view, layoutParams);
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
}
android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@f8ec928 -- permission denied for window type 2002
try {
mWindowManager.addView(mDecorView, mWindowParams);
} catch (NullPointerException | IllegalStateException |
IllegalArgumentException | WindowManager.BadTokenException e) {
// 如果这个 View 对象被重复添加到 WindowManager 则会抛出异常
// java.lang.IllegalStateException: View has already been added to the window manager.
}
//下面这个是更新view
try {
mWindowManager.updateViewLayout(mDecorView, mWindowParams);
} catch (IllegalArgumentException e) {
// 当 WindowManager 已经消失时调用会发生崩溃
// IllegalArgumentException: View not attached to window manager
}
try {
mWM.addView(mView, mParams);
} catch (WindowManager.BadTokenException e) {
/* ignore */
}
ExceptionReporter.reportCrash("Float FloatWindow updateViewLayout", e);
ExceptionReporter.setExceptionReporter(ExceptionHelperImpl())
public class ExceptionReporterImpl extends ExceptionReporter {
@Override
protected void reportCrash(Throwable throwable) {
//壳工程中可以拿到APM,比如上传到bugly平台上
}
@Override
protected void reportCrash(String tag, Throwable throwable) {
}
}


