代码之家  ›  专栏  ›  技术社区  ›  SudoPlz

我应该使用哪个线程来调用react native ui组件内的uiManager调用?

  •  0
  • SudoPlz  · 技术社区  · 8 年前

    我在建一个 本机UI组件 对于使用扩展 ReactRootView .

    在我的视图(名为 SyncRootView )如果我检查线程 Thread curThread = Thread.current(); // main 所以我们在主线上。

    问题是如果我尝试运行 uiManager 呼叫(例如 uiManager.createView ,我收到该错误:

    FATAL EXCEPTION: main
     Process: com.rnexample, PID: 16424
     java.lang.AssertionError
         at com.facebook.infer.annotation.Assertions.assertCondition(Assertions.java:66)
         at com.facebook.react.common.SingleThreadAsserter.assertNow(SingleThreadAsserter.java:27)
         at com.facebook.react.uimanager.ShadowNodeRegistry.getNode(ShadowNodeRegistry.java:67)
         at com.facebook.react.uimanager.UIImplementation.createView(UIImplementation.java:278)
         at com.facebook.react.uimanager.UIManagerModule.createView(UIManagerModule.java:364)
         at com.sudoplz.rnsynchronouslistmanager.Sync.SyncRootView$3.run(SyncRootView.java:177)
         at android.os.Handler.handleCallback(Handler.java:751)
         at android.os.Handler.dispatchMessage(Handler.java:95)
         at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:31)
         at android.os.Looper.loop(Looper.java:154)
         at android.app.ActivityThread.main(ActivityThread.java:6119)
         at java.lang.reflect.Method.invoke(Native Method)
         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
    

    所以基本上问题是一个叫做 SingleThreadAsserter 部分 react-native 我甚至不知道它为什么会在那里。 它是 mThread 值设置为 native_module_thread... 因此我得到 AssertionError 因为我在主线上。

    如果我尝试运行这些 uiManager 调用native\u模块线程(通过使用 ctx.runOnNativeModulesQueueThread(myRunnable) ),一开始似乎是可行的,但后来(我想一旦模块初始化结束??)我明白了

    Tried to enqueue runnable on already finished thread: 'native_modules... dropping Runnable.
    02-21 01:55:36.415 17126-17126/com.rnexample W/MessageQueue: Handler (com.facebook.react.bridge.queue.MessageQueueThreadHandler) {bda653f} sending message to a Handler on a dead thread
     java.lang.IllegalStateException: Handler (com.facebook.react.bridge.queue.MessageQueueThreadHandler) {bda653f} sending message to a Handler on a dead thread
         at android.os.MessageQueue.enqueueMessage(MessageQueue.java:543)
         at android.os.Handler.enqueueMessage(Handler.java:643)
         at android.os.Handler.sendMessageAtTime(Handler.java:612)
         at android.os.Handler.sendMessageDelayed(Handler.java:582)
         at android.os.Handler.post(Handler.java:338)
         at com.facebook.react.bridge.queue.MessageQueueThreadImpl.runOnQueue(MessageQueueThreadImpl.java:61)
         at com.facebook.react.bridge.ReactContext.runOnNativeModulesQueueThread(ReactContext.java:287)
         at com.sudoplz.rnsynchronouslistmanager.Sync.SyncRootView.dispatchInUIThread(SyncRootView.java:516)
         at com.sudoplz.rnsynchronouslistmanager.Sync.SyncRootView.runApplication(SyncRootView.java:188)
         at com.sudoplz.rnsynchronouslistmanager.Sync.SyncRootView.<init>(SyncRootView.java:97)
         at com.sudoplz.rnsynchronouslistmanager.Sync.SyncRootView.<init>(SyncRootView.java:61)
         at com.sudoplz.rnsynchronouslistmanager.List.SPView.<init>(SPView.java:20)
         at com.sudoplz.rnsynchronouslistmanager.SynchronousListManager.createViewInstance(SynchronousListManager.java:37)
         at com.sudoplz.rnsynchronouslistmanager.SynchronousListManager.createViewInstance(SynchronousListManager.java:19)
         at com.facebook.react.uimanager.ViewManager.createView(ViewManager.java:44)
         at com.facebook.react.uimanager.NativeViewHierarchyManager.createView(NativeViewHierarchyManager.java:224)
         at com.facebook.react.uimanager.UIViewOperationQueue$CreateViewOperation.execute(UIViewOperationQueue.java:153)
         at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:813)
         at com.facebook.react.uimanager.UIViewOperationQueue.flushPendingBatches(UIViewOperationQueue.java:926)
         at com.facebook.react.uimanager.UIViewOperationQueue.access$2100(UIViewOperationQueue.java:47)
         at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:986)
         at com.facebook.react.uimanager.GuardedFrameCallback.doFrame(GuardedFrameCallback.java:31)
         at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:136)
         at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame(ChoreographerCompat.java:107)
         at android.view.Choreographer$CallbackRecord.run(Choreographer.java:872)
         at android.view.Choreographer.doCallbacks(Choreographer.java:686)
         at android.view.Choreographer.doFrame(Choreographer.java:618)
         at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
         at android.os.Handler.handleCallback(Handler.java:751)
         at android.os.Handler.dispatchMessage(Handler.java:95)
         at android.os.Looper.loop(Looper.java:154)
         at android.app.ActivityThread.main(ActivityThread.java:6119)
         at java.lang.reflect.Method.invoke(Native Method)
         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
    

    有什么想法吗?

    1 回复  |  直到 8 年前
        1
  •  2
  •   SudoPlz    8 年前

    我最终做到了:

    关于我的构造函数 ReactRootView 我做到了:

    nativeModulesThread = (MessageQueueThreadImpl) ctx.getCatalystInstance().getReactQueueConfiguration().getNativeModulesQueueThread(); 其中ctx是 ReactContext 可用于每个UI本机组件。

    然后我创建了这个方法:

    protected void dispatchInAppropriateThread(Runnable runnable) {
        if (runnable == null) {
            return;
        }
    
        if (nativeModulesThread.getLooper().getThread().isAlive()) {
            ctx.runOnNativeModulesQueueThread(runnable);
        } else {
            this.post(runnable);
        }
    }
    

    所以现在每当我需要运行runnable时,我都会:

    dispatchInAppropriateThread(new Runnable() {
        @Override
        public void run() {
            // do cool stuff
        }
    });