Xtendroid是一款Android的领域特定语言,它大大降低样板代码,同时提供巨大的工具支持。Xtendroid利用Xtend transpiler实现,它的特点是能够在Java代码编辑或编译期间具有拓展方法和活动注释(实时编辑代码生成器)功能。活动注释,他特别能够让Xtend比Kotlin或者Groovy语言更加适合DSL的创建。Xtendroid支持的Eclipse和IntelliJ/ Android Studio,其中包括代码完成,调试等。

举例特点

Anonymous inner classes (lambdas)

Android code:

// get button widget, set onclick handler to toast a message
Button myButton = (Button) findViewById(R.id.my_button);
myButton.setOnClickListener(new View.OnClickListener() {
   public void onClick(View v) {
      Toast.makeText(this, "Hello, world!", Toast.LENGTH_LONG).show();
   }
});

Xtendroid code:

import static extension org.xtendroid.utils.AlertUtils.* // for toast(), etc.
// myButton references getMyButton(), a lazy-getter generated by @AndroidActivity
myButton.onClickListener = [View v|    // Lambda - params are optional
   toast("Hello, world!")
]

Note: Semi-colons optional, compact and differentiating lambda syntax, getters/setters as properties.

Type Inference

Android code:

// Store JSONObject results into an array of HashMaps
ArrayList<HashMap<String,JSONObject>> results = new ArrayList<HashMap<String,JSONObject>>();
HashMap<String,JsonObject> result1 = new HashMap<String,JSONObject>();
result1.put("result1", new JSONObject());
result2.put("result2", new JSONObject());
results.put(result1);
results.put(result2);

Xtendroid (Xtend) code:

var results = #[
    #{ "result1" -> new JSONObject },
    #{ "result2" -> new JSONObject }
]

Note: compact notation for Lists and Maps, method call brackets are optional

Multi-threading

Blink a button 3 times (equivalent Android code is too verbose to include here):

import static extension org.xtendroid.utils.AsyncBuilder.*
// Blink button 3 times using AsyncTask
async [
    // this is the doInBackground() code, runs in the background
    for (i : 1..3) { // number ranges, nice!
        runOnUiThread [ myButton.pressed = true ]
        Thread.sleep(250) // look ma! no try/catch!
        runOnUiThread [ myButton.pressed = false ]
        Thread.sleep(250)
    }
    return true
].then [result|
    // This is the onPostExecute() code, runs on UI thread
    if (result) {
        toast("Done!")
    }
].onError [error|
    toast("Oops! " + error.message)
].start()

Note: sneaky throws, smoother error handling. See documentation for the many other benefits to using the AsyncBuilder.

Android boilerplate removal

Creating a Parcelable in Android:

public class Student implements Parcelable {
    private String id;
    private String name;
    private String grade;
    // Constructor
    public Student(){
    }
    // Getter and setter methods
    // ... ommitted for brevity!
    // Parcelling part
    public Student(Parcel in){
        String[] data = new String[3];
        in.readStringArray(data);
        this.id = data[0];
        this.name = data[1];
        this.grade = data[2];
    }
    @Оverride
    public int describeContents(){
        return 0;
    }
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeStringArray(new String[] {this.id,
                                            this.name,
                                            this.grade});
    }
    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public Student createFromParcel(Parcel in) {
            return new Student(in); 
        }
        public Student[] newArray(int size) {
            return new Student[size];
        }
    };
}

Xtendroid:

// @Accessors creates getters/setters, @AndroidParcelable makes it parcelable!
@Accessors @AndroidParcelable class Student {
    String id
    String name
    String grade
}

Note: the above Xtendroid code essentially generates the same Android code above, into the build/generated folder, which gets compiled normally. Full bi-directional interoperability with existing Java classes.

Functional programming

@Accessors class User {
    String username
    long salary
    int age
}
var List<User> users = getAllUsers() // from somewhere...
var result = users.filter[ age >= 40 ].maxBy[ salary ]
toast('''Top over 40 is «result.username» earning «result.salary»'''

Note: String templating, many built-in list comprehension functions, lambdas taking a single object parameter implicitly puts in scope.

Builder pattern

// Sample Builder class to create UI widgets, like Kotlin's Anko
class UiBuilder {
   def static LinearLayout linearLayout(Context it, (LinearLayout)=>void initializer) {
      new LinearLayout(it) => initializer
   }
   def static Button button(Context it, (Button)=>void initializer) {
      new Button(it) => initializer
   }

// Now let's use it!
import static extension org.xtendroid.utils.AlertUtils.*
import static extension UiBuilder.*
contentView = linearLayout [
   gravity = Gravity.CENTER
   addView( button [
      text = "Say Hello!"
      onClickListener = [ 
         toast("Hello Android from Xtendroid!")
      ]
   ])
]

Note: You can create your own project-specific DSL!

Utilities

import static extension org.xtendroid.utils.AlertUtils.*
import static extension org.xtendroid.utils.TimeUtils.*
var Date yesterday = 24.hours.ago
var Date tomorrow = 24.hours.fromNow
var Date futureDate = now + 48.days + 20.hours + 2.seconds
if (futureDate - now < 24.hours) {
    confirm("Less than a day to go! Do it now?") [
        // user wants to do it now
        doIt()
    ] 
}

Note: using all of the above makes writing unit tests and instrumentation tests very easy, and fun!

最新文章

  1. Module-Zero之版本管理
  2. jstl catch if choose标签
  3. PAT题库-1064. Complete Binary Search Tree (30)
  4. sharepoint列表如何进行随机取几条记录?
  5. Hbase之缓存扫描加快读取速度
  6. js判断是不是chrome浏览器
  7. Android 中解析 JSON
  8. leetcode Largest Rectangle in Histogram 解法二
  9. 深入理解计算机系统第二版习题解答CSAPP 2.15
  10. SQLServer通过链接服务器远程删除数据性能问题解决
  11. w3school之HTML学习笔记
  12. crontab定时任务以及其中中文乱码问题
  13. CentOS6 图形界面(gnome)安装,使用vnc进行远程连接
  14. python 使用Nginx和uWSGI来运行Python应用
  15. Java流程控制语句和数组整理
  16. SQL语法基础之ALTER语句
  17. window自带的公式面板
  18. 解决jar格式文件,双击不能直接运行问题
  19. FSCapture注册码
  20. DockerHub基于Github自己主动化构建

热门文章

  1. 第一个web 程序(servlet 和 jsp )&amp;
  2. linux系统下,在用户空间应用程序中模拟发送系统键盘事件
  3. 初始STM32
  4. Eclipse一些技巧
  5. asp.net core-1.在控制台创建ASP.NET Core应用程序
  6. 11. Java方法的定义与使用
  7. MySql翻页查询
  8. Go part 1 初探
  9. Linux 命令实战
  10. SIP协议参数详解