如何从 WebInterface 更改导航抽屉菜单项的可见性

How to change navigation drawer menu items visibility from WebInternface

我正在编写一个 android 应用程序,仅使用网络视图和网络界面。 我有一个带有菜单项的导航抽屉,我需要更改不同类型用户(f.e 版主、卖家等)的菜单可见性。为此,我从 WebInterface 调用 js 中的 setItemVisible() 函数,但它不起作用。 这是我的 WebInterface 代码

package com.example.samosval;

import ...

class WebAppInterface{
Context mContext;
private DomainLoadStoreParameter resources;

/** Instantiate the interface and set the context */
WebAppInterface(Context c) {
    mContext = c;
}

@JavascriptInterface
public void setItemVisible(String name) {
    try {
        NavigationView navigationView = (NavigationView) ((Activity) mContext).findViewById(R.id.nav_view);
        MenuItem menuItem = navigationView.getMenu().findItem(getResId(name, R.id.class));
        menuItem.setVisible(true);
    } catch (Exception e) {
        Log.e("TAGIF", "setItemVisible: ", e);
    }
}

public static int getResId(String resName, Class<?> c) {

    try {
        Field idField = c.getDeclaredField(resName);
        return idField.getInt(idField);
    } catch (Exception e) {
        e.printStackTrace();
        return -1;
    }
}
}

但是出现这样的错误

12-17 21:07:58.406 2229-2386/com.arystankaliakparov.samosval E/TAGIF: setItemVisible: 
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7234)
    at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1070)
    at android.view.View.requestLayout(View.java:17932)
    at android.view.View.requestLayout(View.java:17932)
    at android.view.View.requestLayout(View.java:17932)
    at android.view.View.requestLayout(View.java:17932)
    at android.view.View.requestLayout(View.java:17932)
    at android.view.View.requestLayout(View.java:17932)
    at android.support.v4.widget.DrawerLayout.requestLayout(DrawerLayout.java:1303)
    at android.view.View.requestLayout(View.java:17932)
    at android.view.View.requestLayout(View.java:17932)
    at android.support.v7.widget.RecyclerView.requestLayout(RecyclerView.java:4202)
    at android.support.v7.widget.RecyclerView$RecyclerViewDataObserver.onChanged(RecyclerView.java:5286)
    at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:11997)
    at android.support.v7.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:7070)
    at android.support.design.internal.NavigationMenuPresenter$NavigationMenuAdapter.update(NavigationMenuPresenter.java:474)
    at android.support.design.internal.NavigationMenuPresenter.updateMenuView(NavigationMenuPresenter.java:114)
    at android.support.v7.view.menu.MenuBuilder.dispatchPresenterUpdate(MenuBuilder.java:298)
    at android.support.v7.view.menu.MenuBuilder.onItemsChanged(MenuBuilder.java:1069)
    at android.support.v7.view.menu.MenuBuilder.onItemVisibleChanged(MenuBuilder.java:1108)
    at android.support.v7.view.menu.MenuItemImpl.setVisible(MenuItemImpl.java:665)
    at com.arystankaliakparov.samosval.WebAppInterface.setItemVisible(WebAppInterface.java:46)
    at org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
    at org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:53)
    at android.os.Handler.dispatchMessage(Handler.java:111)
    at android.os.Looper.loop(Looper.java:194)
    at android.os.HandlerThread.run(HandlerThread.java:61)

您需要从主线程更新 UI。使用 运行OnUiThread,您可以更新它。

runOnUiThread(new Runnable() {
 @Override
 public void run() {
    // Update UI
 }
});

Activity.runOnUiThread 文档

将 this 嵌套在方法中,然后将原始代码放入 运行 函数中。仅包含尽可能少的代码,否则您将开始破坏后台线程的目的。