Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/203.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将java转换为kotlin中断上下文菜单_Java_Android_Kotlin_Contextmenu - Fatal编程技术网

将java转换为kotlin中断上下文菜单

将java转换为kotlin中断上下文菜单,java,android,kotlin,contextmenu,Java,Android,Kotlin,Contextmenu,我一直在将一个项目转换为Kotlin,发现了一个问题。java代码的上下文菜单在生成的kotlin中被破坏。这是对项目源代码的简化测试。它只包含一个具有单个布局和上下文菜单的主活动。java版本可以工作,但kotlin版本崩溃。我能想到的唯一不寻常的是,我正在注册的视图是RelativeLayout中的imageView java.lang.NullPointerException: Parameter specified as non-null is null:

我一直在将一个项目转换为Kotlin,发现了一个问题。java代码的上下文菜单在生成的kotlin中被破坏。
这是对项目源代码的简化测试。它只包含一个具有单个布局和上下文菜单的主活动。java版本可以工作,但kotlin版本崩溃。我能想到的唯一不寻常的是,我正在注册的视图是RelativeLayout中的imageView

 java.lang.NullPointerException:
        Parameter specified as non-null is null: 
        method kotlin.jvm.internal.Intrinsics.checkNotNullParameter
        , parameter menuInfo
    at com...MainActivity.onCreateContextMenu(MainActivity.kt)
    at android.view.View.createContextMenu(View.java:8392)
    at com.android.internal.view.menu.ContextMenuBuilder
        .show(ContextMenuBuilder.java:81)
    at com.android.internal.policy.impl
        .PhoneWindow$DecorView
        .showContextMenuForChild(PhoneWindow.java:2517)
    at android.view.ViewGroup.showContextMenuForChild(ViewGroup.java:658)
MainActivity.java是:

public class MainActivity extends AppCompatActivity {
    private static int animationSpeed = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        registerForContextMenu(findViewById(R.id.imageView));
    }
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
                ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.speed_select, menu);
        menu.getItem(animationSpeed).setChecked(true);
    }
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        int itemId = item.getItemId();
        boolean rv = true;
        switch(itemId) {
            case R.id.animate_slow: animationSpeed = 0; break;
            case R.id.animate_normal: animationSpeed = 1; break;
            case R.id.animate_fast: animationSpeed = 2; break;
            default: Log.d("onContextItemSelected", String.format(
                    "menu item unhandled:0x%08x", itemId)
            );
                rv = false;
        }
        return rv;
    }
}
MainActivity.kt是:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        registerForContextMenu(findViewById(R.id.imageView))
    }
    override fun onCreateContextMenu(menu: ContextMenu, v: View,
                                     menuInfo: ContextMenuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo)
        val inflater = menuInflater
        inflater.inflate(R.menu.speed_select, menu)
        menu.getItem(animationSpeed).isChecked = true
    }
    override fun onContextItemSelected(item: MenuItem): Boolean {
        val itemId = item.itemId
        var rv = true
        when (itemId) {
            R.id.animate_slow -> animationSpeed = 0
            R.id.animate_normal -> animationSpeed = 1
            R.id.animate_fast -> animationSpeed = 2
            else -> {
                Log.d("onContextItemSelected", String.format(
                        "menu item unhandled:0x%08x", itemId))
                rv = false
            }
        }
        return rv
    }
    companion object {
        private var animationSpeed = 0
    }
}
我的菜单文件是:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <group 
        android:checkableBehavior="single"
        android:id="@+id/animate_speed" >
       <item android:id="@+id/animate_slow"
             android:title="@string/slow" />
       <item android:id="@+id/animate_normal"
             android:title="@string/normal" />
       <item android:id="@+id/animate_fast"
             android:title="@string/fast" />
       </group>
</menu>
对Java代码的测试表明编译器和lint都很满意,代码仍在运行。我再次在转换过程中运行jave,得到的函数kotlin签名是:

override fun onCreateContextMenu(
    menu: ContextMenu, v: View,
    menuInfo: ContextMenuInfo?)
我测试了Kotlin,现在也可以了

注意:为了您的启发和娱乐,我将消息来源发布在
.

我只是对我的问题给出了这个答复,这样人们就会注意到,多亏了一位评论者,才找到了解决方案。此修复仅适用于使用菜单列表而不是创建单个菜单项的情况,并且由于Kotlin处理空安全性的方式,此修复仅对Kotlin必要。请看问题的结尾和我对该问题的评论,

Steve S.

Java代码有
ContextMenu.ContextMenuInfo menuInfo
,指定
ContextMenuInfo
ContextMenu
的静态成员类,而Kotlin代码只有
menuInfo:ContextMenuInfo
?在
MainActivity#onCreateContextMenu
中,我想我找到了问题-检查-所以应该是
menuInfo:ContextMenuInfo?
-我想这只是一种向编译器发出信号的方式,表明
null
是参数的有效值。如果Kotlin知道值永远不会为
null
,它可能会优化您的代码。谢谢@JonnyHenly!我永远也找不到。我将在我的问题上贴一张便条,解释解决方案。这是一只虫子吗?如果是这样(对我来说这看起来像一个bug),我应该向谁报告它?所以它闻起来确实像一个bug,特别是对于Android SDK中这样一个被重写的方法,但是我认为这更多的是Java->Kotlin转换器的限制。如果该方法在早期检查
if(menuItem==null)
,然后在参数类型中添加
,那么就可以进行解析了。同时,我从来没有尝试过创建转换器,所以我确信有很多警告和异常值会让这个评论看起来很愚蠢。我对此做了更多的研究。我认为我出现问题的原因是,我没有创建菜单项,而是使用menu.xml布局并对其进行膨胀,因此我不在这里查看单个菜单项。使用此样式,我将捕捉onContextItemSelected中的菜单选择。所以——在我的例子中,菜单项为null,因为没有单独的菜单项,字段应该是@null。我查找了Activity.onCreateContextMenu的源代码,但它似乎不在线。在任何情况下,修复都是有效的。如果有人发现与此相反的信息,请让我知道。在我看来,一般来说,最好让评论人提交并回答,这样你就可以投票并接受它。而且,把答案放在答案中,而不是放在问题上,更干净。(只是说了,如果你愿意的话,你可以考虑下一个问题)。当做
public void onCreateContextMenu(
    ContextMenu menu, View v,
    @Nullable ContextMenu.ContextMenuInfo menuInfo)
override fun onCreateContextMenu(
    menu: ContextMenu, v: View,
    menuInfo: ContextMenuInfo?)