如何在Android上调用Clojure? [英] How does one invoke Clojure on Android?

查看:101
本文介绍了如何在Android上调用Clojure?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TL; DR:我无法在Android中调用Clojure方法.我收到错误消息,我不确定为什么.

TL;DR: I can't invoke Clojure methods in Android; I get an error and I'm not sure why.

我正在为学校项目构建一个Android应用程序.我已经学习了Clojure,并且希望将其用于我的应用程序的某些部分.(我不是的目的是要用Clojure编写整个程序,只是几个库.)

I am building an Android app for a school project. I've learned Clojure, and I would like to use it for parts of my application. (I am not aiming to write the entire thing in Clojure—just a few libraries.)

我已经能够将Clojure程序编译为 .jar 并从笔记本电脑上运行的Java调用它,但我什至无法在Android应用程式!我猜我想念图书馆或其他东西,但是我在这里很漂亮.

I've been able to compile a Clojure program into a .jar and invoke it from Java running on my laptop, but I haven't been able to call even built-in functions in an Android app! I’m guessing I’m missing a library or something, but I’m pretty at sea here.

我进行了以下测试:

MainActivity.java :

package org.wiersdorf.ashton.clojureinterop;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import clojure.java.api.Clojure;
import clojure.lang.IFn;

public class MainActivity extends AppCompatActivity {

    private Button BoomButton;
    private TextView myText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        BoomButton = (Button) findViewById(R.id.my_button);
        myText   = (TextView) findViewById(R.id.my_text);

        BoomButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                IFn plus = Clojure.var("clojure.core", "+");
                String foo = plus.invoke(1, 2).toString();
                myText.setText("Text: " + foo);
            }
        });

    }
}

activity_main.xml :

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/my_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/my_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/my_text" />

</android.support.constraint.ConstraintLayout>

当我单击显示的按钮时,这是我得到的错误:

When I click the button that shows up, this is the error I get:

2018-11-17 23:05:01.313 16202-16202/org.wiersdorf.ashton.clojureinterop E/AndroidRuntime: FATAL EXCEPTION: main
    Process: org.wiersdorf.ashton.clojureinterop, PID: 16202
    java.lang.ExceptionInInitializerError
        at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:97)
        at clojure.core$fn__8373.invokeStatic(core.clj:7032)
        at clojure.core$fn__8373.invoke(core.clj:7027)
        at clojure.core__init.load(Unknown Source:7027)
        at clojure.core__init.<clinit>(Unknown Source:94)
        at java.lang.Class.classForName(Native Method)
        at java.lang.Class.forName(Class.java:453)
        at clojure.lang.RT.classForName(RT.java:2205)
        at clojure.lang.RT.classForName(RT.java:2214)
        at clojure.lang.RT.loadClassForName(RT.java:2233)
        at clojure.lang.RT.load(RT.java:451)
        at clojure.lang.RT.load(RT.java:426)
        at clojure.lang.RT.doInit(RT.java:469)
        at clojure.lang.RT.<clinit>(RT.java:336)
        at clojure.lang.Namespace.<init>(Namespace.java:34)
        at clojure.lang.Namespace.findOrCreate(Namespace.java:176)
        at clojure.lang.Var.intern(Var.java:151)
        at clojure.java.api.Clojure.var(Clojure.java:82)
        at clojure.java.api.Clojure.<clinit>(Clojure.java:96)
        at clojure.java.api.Clojure.var(Clojure.java:82)
        at org.wiersdorf.ashton.clojureinterop.MainActivity$1.onClick(MainActivity.java:28)
        at android.view.View.performClick(View.java:6294)
        at android.view.View$PerformClick.run(View.java:24770)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
     Caused by: java.lang.NoSuchMethodException: canAccess [class java.lang.Object]
        at java.lang.invoke.MethodHandles$Lookup.findVirtual(MethodHandles.java:906)
        at clojure.lang.Reflector.<clinit>(Reflector.java:38)

有什么想法吗?提前致谢.:)

Any ideas? Thanks in advance. :)

推荐答案

在Java 9中添加了 canAccess 方法(请参见

The method canAccess was added in Java 9 (see here).

从显示为 canAccess 的NoSuchMethodException的堆栈跟踪来看,您使用的是用Java 9或更高版本编译的Clojure jar,而您的Android系统使用的是较早的JRE.

Judging by that stacktrace, which shows a NoSuchMethodException for canAccess, you're using a Clojure jar that was compiled with Java 9 or above, and your Android system is using an earlier JRE.

如果您可以在Android上升级JRE,或切换到兼容的Clojure版本,则应该对其进行修复.

If you can either upgrade your JRE on Android, or switch to a compatible version of Clojure, that should fix it.

这篇关于如何在Android上调用Clojure?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆