Android view.post() 方法使用技巧

本文介绍了如何使用View的post()方法来确保视图操作在视图已附加到窗口后执行,这对于避免因试图过早显示PopupWindow而引发的BadTokenException等问题非常有用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 需要当前view 在attachedToWindow之后执行操作 就可以使用 view的post 方法,方法如下 

view.post(new Runnable() {
            @Override
            public void run() {
                
            }
});

 

其run方法调用时机: post方法会自动分两种情况处理,当 View 还没 attachedToWindow 时,会先将这些 Runnable 操作缓存下来,等attachedToWindow之后在主线程执行,否则就直接通过 mAttachInfo.mHandler 将这些 Runnable 操作 post 到主线程的 MessageQueue 中等待执行。

举个栗子:正常popupwindow 是不能在activity的 onCreate 方法执行的,需要在其依附的view 绑定到Window时(attachedToWindow) 才能显示,否则就会报:.android.view.WindowManager$BadTokenException: Unable to add window --token null is not valid; is your activity running?

所以使用其post方法,就完全没有问题啦

View view = find(android.R.id.content);
view.post(new Runnable() {
            @Override
            public void run() {
                //显示pop
                pop.showAtLocation(view, Gravity.CENTER,0,0);
            }
});

还有 view.postDelayed 也是一样的

08-04 12:17:44.700 30976 30976 E OplusA7ThreadExtImpl: Failed to parse DragConfig, errorMsg = Attempt to invoke virtual method 'android.view.viewdrag.bean.ConfigDragInfo android.view.viewdrag.bean.PackageDragConfigInfo.getConfigDragInfo()' on a null object reference java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.viewdrag.bean.ConfigDragInfo android.view.viewdrag.bean.PackageDragConfigInfo.getConfigDragInfo()' on a null object reference at android.view.viewdrag.OplusViewDragManager.setDragConfig(OplusViewDragManager.java:141) at android.view.viewdrag.OplusSmartLoopDragManager.init(OplusSmartLoopDragManager.java:82) at android.app.OplusActivityThreadExtImpl.hookHandleBindApplication(OplusActivityThreadExtImpl.java:996) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7940) at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2654) at android.os.Handler.dispatchMessage(Handler.java:112) at android.os.Looper.loopOnce(Looper.java:288) at android.os.Looper.loop(Looper.java:393) at android.app.ActivityThread.main(ActivityThread.java:9564) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:600) at com.android.internal.os.ChildZygoteInit.runZygoteServer(ChildZygoteInit.java:136) at com.android.internal.os.WebViewZygoteInit.main(WebViewZygoteInit.java:147) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:600) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1010)
08-06
java.lang.Throwable: Unlocked access to synchronized WindowContainer at com.android.server.wm.WindowManagerServiceExtImpl.unlockedAccessToWindowContainer(WindowManagerServiceExtImpl.java:1313) at com.android.server.wm.WindowManagerServiceExtImpl.checkWindowContainerPreconditions(WindowManagerServiceExtImpl.java:1292) at com.android.server.wm.WindowContainer.checkPreconditions(WindowContainer.java:875) at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:2373) at com.android.server.wm.DisplayArea.forAllRootTasks(DisplayArea.java:476) at com.android.server.wm.FlexibleTaskController.findTopFlexibleTask(FlexibleTaskController.java:8515) at com.android.server.wm.FlexibleTaskController.getTopZoomTask(FlexibleTaskController.java:8427) at com.android.server.wm.FlexibleWindowManagerService.isInFlexibleWindowHandleRegion(FlexibleWindowManagerService.java:9638) at com.android.server.wm.OplusSplitScreenManagerService.inFlexibleWindowHandleRegion(OplusSplitScreenManagerService.java:3368) at com.android.server.wm.OplusSplitScreenManagerService.inSplitHandleRegion(OplusSplitScreenManagerService.java:3348) at com.android.server.wm.SystemGesturesPointerEventListenerExtImpl.inSplitHandleRegion(SystemGesturesPointerEventListenerExtImpl.java:225) at com.android.server.wm.SystemGesturesPointerEventListener.onPointerEvent(SystemGesturesPointerEventListener.java:266) at com.android.server.wm.PointerEventDispatcher.onInputEvent(PointerEventDispatcher.java:69) at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:321) at android.os.MessageQueue.nativePollOnce(Native Method) at android.os.MessageQueue.nextConcurrent(MessageQueue.java:856) at android.os.MessageQueue.next(MessageQueue.java:1047) at android.os.Looper.loopOnce(Looper.java:221) at android.os.Looper.loop(Looper.java:408) at android.os.HandlerThread.run(HandlerThread.java:85) at com.android.server.ServiceThread.run(ServiceThread.java:49) at com.android.server.UiThread.run(UiThread.java:65)
最新发布
08-10
分析以下报错; FATAL EXCEPTION: main Process: com.example.contacts2, PID: 12148 java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.contacts2/com.example.contacts2.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4186) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4467) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:222) at android.app.servertransaction.TransactionExecutor.executeNonLifecycleItem(TransactionExecutor.java:133) at android.app.servertransaction.TransactionExecutor.executeTransactionItems(TransactionExecutor.java:103) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:80) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2823) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loopOnce(Looper.java:248) at android.os.Looper.loop(Looper.java:338) at android.app.ActivityThread.main(ActivityThread.java:9067) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:932) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:208) at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:174) at android.content.Context.obtainStyledAttributes(Context.java:1103) at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:922) at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:889) at androidx.appcompat.app.AppCompatDelegateImpl.findViewById(AppCompatDelegateImpl.java:691) at androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:264) at com.example.contacts2.MainActivity.<init>(MainActivity.java:36) at java.lang.Class.newInstance(Native Method) at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95) at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45) at android.app.Instrumentation.newActivity(Instrumentation.java:1443) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4173) ... 13 more
07-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值