簡體   English   中英

如何在Android上運行Frege程序?

[英]How to run Frege programs on Android?

我對函數式語言的Android編程感興趣,最好是接近Haskell。 弗雷格似乎是一個不錯的選擇。 我發現有人已經做過這樣的概念驗證應用程序 ,但我找不到它的來源或類似的東西。

所以我的問題是,如何在Android上運行Frege程序,它有多難以及最終的障礙是什么?

我看到的主要障礙是,目前無法將frege源編譯為實現某個接口或擴展另一個類的java類。

相反,從frege模塊生成的java類只是靜態方法和您定義的其他東西的命名空間。

因此,要制作一個簡單的Android項目,從frege調用java是不夠的,這很容易,但也可以從java調用frege。 換句話說,你需要字面意義上的完整* inter *可操作性。

當然,這是可能的,但必須說代碼生成並不是為了方便java使用而設計的。

我還沒有完成Android項目,因此我不確定需要多少膠水代碼。

最后一個警告:Gabriel Riba之前的工作是使用早期版本的編譯器完成的。 甚至還有支持JDK6的frege發行版的鏈接 - 請不要使用它,它與更新的版本不兼容。

如果你願意接受它,你將通過上面提到的谷歌小組獲得所有可能的支持。 如果有人制作並記錄了一些“規范”的方法來實現這一點,那就太棒了。

我不熟悉frege,我沒有嘗試在Android上使用scala或其他JVM語言。

話雖這么說,如果我嘗試這樣的話,這些是我可能會采取的步驟,試圖找出如何讓它發揮作用。

  1. 在frege中構建一個基於命令行的HelloWorld類型應用程序,可以運行,例如java -jar HelloWorld.jar HelloWorld

  2. 在HelloWorld.jar上運行dx,然后嘗試使用dalvikvm從adb shell獲取Android設備上的示例。 即dalvikvm -cp blah.dex HelloWorld

  3. 弄清楚如何從frege中的Android sdk提供的android.jar中引用/使用類

  4. 在frege中構建一個簡單的概念證明Activity類,並從中手動構建一個classes.dex文件

  5. 在java中構建類似的概念驗證應用程序,並使用現有的android工具構建apk

  6. 替換apk中的classes.dex,重新簽名apk,看看它是否有效

  7. 如果你得到那么多工作,那么從那里,你可以為frege工作更好的構建故事,使用aapt編譯資源並最終從頭開始構建一個完整的apk。

從我可以通過快速網絡搜索中收集到的一切,包括來自frege - 編程語言郵件列表的一些命中,它看起來不像只有Frege的Android應用程序。

相反,您必須使用其他一些支持Android的語言並使用它來調用您的Frege代碼。 生成這樣的“存根”可能會自動完成,但我沒有看到現有的工具。

圍繞由Frege和Android的Java編譯器生成的Java代碼也存在問題,但這似乎是使用逆轉換工具相對容易解決的問題。

https://groups.google.com/forum/#!topic/frege-programming-language/Ounzmu-oHJQ https://groups.google.com/forum/#!topic/frege-programming-language/8bkWorojiiY

我還希望有參考多態性和ad-hoc多態性可用於Android開發的參考透明,強類型語言。 雖然缺少,但我建議Scala進行Android開發。

如果你想在弗雷格完​​全寫你的應用程序,這將更棘手。 您需要為Android API編寫包裝器,因為FregeAndroid包裝器似乎缺少某些文件

但是,如果你想用Java編寫你的UI,並為你的應用程序邏輯調用Frege,我有一個示例項目 ,展示了如何做到這一點。

我的示例項目在Frege中有這個功能:

extraText :: String -> String
extraText who = "\nHello, " ++ who ++ "!"

然后我從Java調用:

public class FregeActivity extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView textView = (TextView) findViewById(R.id.txt);
        textView.append(FregeCode.extraText("Android"));
    }
}

看起來像這樣

FregeActivity

我的示例項目使用Frege 3.23,因此您可以使用從Java調用Frege舊方法 我沒有嘗試過使用Frege 3.24,但是如果你想嘗試一下,你會使用新的方法

唯一真正棘手的部分是獲得構建Frege代碼的build.gradle 我開始使用AndreasLändle在Frege郵件列表上發布片段 ,然后我將其充實到一個完整的build.gradle中 我無法讓Proguard工作,因此生成的APK包含整個frege.jar 這有點膨脹應用程序,它需要打開Multidex ,但否則它似乎沒問題。

另外,請注意我的示例項目需要API級別21或更高,因為Frege需要ForkJoinPool ,而Android僅在21級及以上。

對於那些仍然感興趣的人,我在這里有一篇關於它的博客文章。 您必須設置gradle構建以將Frege代碼編譯為java並將其放入java源路徑中。 然后你必須子類化活動並定義一些自定義包裝器

data Bundle = native android.os.Bundle

data Context = native android.content.Context

data FregeActivity = native android.app.Activity where
    native getApplicationContext :: MutableIO FregeActivity -> IO (MutableIO Context)
    native setContentView :: MutableIO FregeActivity -> MutableIO TextView -> IO ()

data TextView = native android.widget.TextView where
    native new :: MutableIO Context -> STMutable RealWorld TextView
    native setText :: MutableIO TextView -> String -> IO ()

onCreateF :: MutableIO FregeActivity -> IO ()
onCreateF !this = do
    context <- this.getApplicationContext
    tv <- TextView.new context
    tv.setText "Hello, Android - Love, Frege"
    this.setContentView tv

native module type FregeActivity where {
    @Override
    public void onCreate(android.os.Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final frege.run7.Func.U<Object,Short> res = RunTM.<frege.run7.Func.U<Object,Short>>cast(onCreateF(this)).call();
        frege.prelude.PreludeBase.TST.run(res).call();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM