Mik*_*yer 38 eclipse android scala
我最近采用了一种使用Scala和Eclipse进行Android编程的方法,它可以在不使用Proguard或Treeshake的情况下减少代码和编译时间.
在本文之后,我应该能够使用最后的Eclipse构建(3.7),几乎是在仿真器版本10上更新的Scala(2.8.1)的最新版本,在Eclipse中的版本2.8.3以及提供的插件.
提出的方法是提供一个特定的ramdisk映像版本,我们可以在其中上传scala库,这会大大缩小要上传到模拟器的代码的大小.
我按照步骤,创建了一个hello world,添加了scala本质,添加了一个虚拟scala类,在Android Package Installer之前移动了Scala构建器,一切都构建完美,但是当我在Eclipse的模拟器上启动apk时,应用程序崩溃了我收到以下错误,看起来与此处提供的 相同(在文档末尾):
03-29 10:29:38.505: E/AndroidRuntime(839): java.lang.NoClassDefFoundError: upg.TestSinceInstallation.ComputeSum
Run Code Online (Sandbox Code Playgroud)
如果我删除活动文件中的scala引用,它运行良好.
这是TestSinceInstallation.java文件:
package upg.TestSinceInstallation;
import android.app.Activity;
import android.os.Bundle;
import upg.TestSinceInstallation.ComputeSum;
public class TestSinceInstallationActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int a = 1;
int b = 5;
ComputeSum cs = new ComputeSum(a, b);
if(cs.getResut() == 6) {
setContentView(R.layout.main);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是ComputeSum.scala文件
package upg.TestSinceInstallation
class ComputeSum(a: Int, b: Int) {
def getResut() : Int = a + b
}
Run Code Online (Sandbox Code Playgroud)
您认为我应该怎么做才能使这项工作成功?我感觉如此接近目标.
Mik*_*yer 56
这是解决方案,使用Android与Eclipse 3.7和Scala 3.0.0没有任何问题.
https://androidproguardscala.s3.amazonaws.com/UpdateSiteForAndroidProguardScala
现在,要创建一个scala项目,
Configure,Add Scala natureAdd AndroidProguardScala nature你完成了.
现在好事发生了.首先,您可以对任何活动进行scalafy,您将可以访问scala的独特功能,例如:
以下是其中一些示例.
package com.example.testing;
import android.app.Activity
import android.os.Bundle
import scala.collection.mutable.Map
import android.view.View
import android.widget.SeekBar
import android.widget.ImageButton
import android.graphics.drawable.Drawable
import android.widget.TextView
trait ActivityUtil extends Activity {
implicit def func2OnClickListener(func: (View) => Unit):View.OnClickListener = {
new View.OnClickListener() { override def onClick(v: View) = func(v) }
}
implicit def func2OnClickListener(code: () => Unit):View.OnClickListener = {
new View.OnClickListener() { override def onClick(v: View) = code() }
}
private var customOnPause: () => Unit = null
override def onPause() = {
super.onPause()
if(customOnPause != null) customOnPause()
}
def onPause(f: =>Unit) = {
customOnPause = {() => f}
}
private var customOnCreate: Bundle => Unit = null
override def onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
if(customOnCreate != null) customOnCreate(savedInstanceState)
}
def onCreate(f: Bundle => Unit) = {
customOnCreate = f
}
// Keep references alive when fetched for the first time.
private implicit val vMap = Map[Int, View]()
private implicit val ibMap = Map[Int, ImageButton]()
private implicit val sbMap = Map[Int, SeekBar]()
private implicit val tvMap = Map[Int, TextView]()
private implicit val dMap = Map[Int, Drawable]()
def findView[A <: View](id: Int)(implicit v: Map[Int, A]): A = v.getOrElseUpdate(id, findViewById(id).asInstanceOf[A])
def findDrawable[A <: Drawable](id: Int)(implicit v: Map[Int, A]): A = v.getOrElseUpdate(id, getResources().getDrawable(id).asInstanceOf[A])
implicit class RichView(b: View) { // Scala 2.10 !
def onClicked(f: =>Unit) = b.setOnClickListener{ () => f }
}
// Implicit functions to operate directly on integers generated by android.
implicit def findViewImageButton(id: Int): ImageButton = findView[ImageButton](id)
implicit def findViewSeekBar(id: Int): SeekBar = findView[SeekBar](id)
implicit def findViewTextView(id: Int): TextView = findView[TextView](id)
implicit def findDrawable(id: Int): Drawable = findDrawable[Drawable](id)
implicit def findRichView(id: Int): RichView = toRichView(findView[View](id))
}
Run Code Online (Sandbox Code Playgroud)
现在,在所有以前的样板之后,编写简洁的活动非常有用.请注意我们如何直接对id进行操作,就像它们是视图一样.需要消除歧义,(view: TextView).requestFocus()好像可以从各种结构推断出方法.
// Now after all the boilerplate, it is very useful to write consise activities
class MyActivity extends Activity with ActivityUtil {
import R.id._ // Contains R.id.button, R.id.button2, R.id.button3, R.id.mytextview
lazy val my_button: ImageButton = button //In reality, R.id.button
lazy val his_button: ImageButton = button2
onCreate { savedInstanceState => // The type is automatically inferred.
setContentView(R.layout.main)
my_button.setOnClickListener(myCustomReactClick _)
his_button.setOnClickListener { () =>
//.... Scala code called after clicking his_button
}
button3.onClicked {
// Awesome way of setting a method. Thanks Scala.
}
mytextview.setText("My text") // Whoaaa ! setText on an integer.
(mytextview: TextView).requestFocus() // Disambiguation because the method is ambiguous
// Note that because of the use of maps, the textview is not recomputed.
}
def myCustomReactClick(v: View) = {
// .... Scala code called after clicking my_button
}
onPause{
// ... Custom code for onPause
}
}
Run Code Online (Sandbox Code Playgroud)
确保scala文件的名称与其中包含的主要活动匹配,在这种情况下应该是MyActivity.scala.
其次,要将scala项目设置为库项目,使用它作为具有不同资源的应用程序的基础,遵循常规方式设置库项目.在要作为一个基础库项目,斯卡拉项目上右键单击Properties,Android并检查isLibrary.
若要使用这个库项目的推导,以及您可以生成APK,创建一个新的Android项目,并且不添加任何阶或androidproguardscala性质,只需右键点击,Properties,Android,并添加以前的斯卡拉项目作为库.
更新使用Android插件的新版本,您应该去Project Properties > Build Päth > Order and Export检查Android Private Libraries.这将允许导出库项目和主项目中的scala库,即使主项目未分配Scala也是如此.
测试使用插件Robolectric可以轻松测试您的Android scala项目.只需按照创建测试项目的步骤,添加Scala特性.您甚至可以使用新的scala调试器,通过添加scalatest库,您可以使用Scala和Scala的许多其他功能.
| 归档时间: |
|
| 查看次数: |
6163 次 |
| 最近记录: |