Android官方数据绑定框架DataBinding(一)

还记得在博客《高逼格UI-ASD(Android Support Design)》的开始曾经说过,Android最新推出了一个官方的数据绑定框架-Data Binding Library。现在github上也有很多三方的数据绑定框架,但是我们为什么要选择官方的呢?恩,答对了。就是因为是官方的,三方的东西说不定什么时候作者一步高兴就停止更新了,官方的就不一样了,我们可以看到它渐渐的稳定起来。好了废话不多说,从这篇博客开始,我们就来了解一下android最新给我们带来的数据绑定框架——Data Binding Library。数据绑定框架给我们带来了更大的方便性,以前我们可能需要在Activity里写很多的findViewById,烦人的代码也增加了我们代码的耦合性,现在我们马上就可以抛弃那么多findViewById。说到这里,有人可能会有个疑问:我使用一些注解框架也可以不用findViewById啊,是的,但是注解注定要拖慢我们代码的速度,Data Binding则不会,官网文档说还会提高解析XML的速度,最主要的Data Binding并不是单单减少了我们的findViewById,更多好处请往下看文章。

一、环境

在开始使用新东西之前,我们需要稍微的配置一下环境,这里要求你的Android Studio版本是1.3+,使用eclipse的同学暂时还没有办法使用该框架,请换用Android Studio。还有,在开始之前,请更新你的Support repository到最新的版本。

万事俱备,那我们就开始搭配环境!

新建一个project,在dependencies中添加以下依赖

classpath "com.android.databinding:dataBinder:1.0-rc1"

新建module,并且在module的build.gradle文件中添加

apply plugin: ‘com.android.application‘
apply plugin: ‘com.android.databinding‘

ok,到现在为止,我们的环境就准备完毕了,下面我们就开始Data Binding的学习啦。

二、Data Binding尝试

在代码开始,我们并不直接进入新东西的讲解,而且以一段代码展现Data Binding的魅力。

首先我们需要一个java bean,很简单,一个学生类。

public class Student {
    private String name;
    private String addr;

    public Student() {
    }

    public Student(String name, String addr) {
        this.name = name;
        this.addr = addr;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddr() {
        return this.addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }
}

再来看看我们布局文件怎么写:

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="stu"
            type="org.loader.androiddatabinding.Student" />
    </data>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{stu.name}"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{stu.addr}"/>
    </LinearLayout>
</layout>

可以看到我们的xml布局和以前还有有一定的差别的,但是差别也不是很大。

最后来看看Activity怎么写。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.setStu(new Student("loader", "山东莱芜"));
    }
}

Activity的代码非常简单,就添加了两行代码,而且,值得注意的是:我们并没有findViewById然后再去setText

这段小代码运行的结果大家可能已经猜到了,就是在界面上显示loader山东莱芜两句话。

)

在看完小实例后,大家是不是感觉棒棒哒? 没有了之前的find控件,没有了setText,Activity代码更加简洁明了!

下面开始,我们进入Data Binding的学习!

三、 初始Data Binding

上面的代码算是带领我们进入了Data Binding的世界,那我们先从布局文件开始入手Data Binding吧。再来看看上面的布局文件。

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="stu"
            type="org.loader.androiddatabinding.Student" />
    </data>
    ...
</layout>

我们的根节点变成了layout,在layout的子节点中分成两部分,第一部分是data节点,第二部分才是我们之前的根节点,在data节点下我们又定义了一个variable

从名称上看,这应该是一个变量,变量的名称是stu,类型是org.loader.androiddatabinding.Student,这类似我们在java文件中这么定义:

  org.loader.androiddatabinding.Student stu;

ok,这样很好理解了吧,不过这里要写Student完整的包名,一个还好,如果这里我们需要多个Student呢?要累死? NO,NO,NO,我们还可以向写java文件那样导入包。

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <import type="org.loader.app2.Student" />
        <variable
            name="stu"
            type="Student" />
    </data>
    ...
</layout>

这样写,就类似于java的

import org.loader.app2.Student;
...
Student stu;
...

既然变量我们定义好了,那该怎么使用呢?还是看上面的xml文件。

<layout xmlns:android="http://schemas.android.com/apk/res/android">
  ...
  <LinearLayout
      android:orientation="vertical"
      android:layout_width="match_parent"
      android:layout_height="wrap_content">
      <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@{stu.name}"/>

      <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@{stu.addr}"/>
  </LinearLayout>
</layout>

恩,注意看两个TextViewandroid:text,它的值是一个以@开始,以{}包裹的形式出现,而内容呢?是stu.name。stu就是我们上面定义的variable,

name还记得吗?是我们Student类中的一个变量。其实这里就会去调用stu.getName()方法。

好了,很快,我们就入门了Data Binding,下面让我们来多定义几个变量试试看。

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <import type="org.loader.app2.Student" />
        <variable
            name="stu"
            type="Student" />
        <variable
            name="str"
            type="String"/>
        <variable
            name="error"
            type="boolean"/>
        <variable
            name="num"
            type="int" />
    </data>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{stu.name}"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{str}"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(num)}"/>
    </LinearLayout>
</layout>

来看看定义的变量,多了好几个,有一个String类型的变量我们并没有导包,这里说明一下,和在java里一样,java.lang包里的类,我们是可以不用导包的,再往下,一个booleanint类型的变量,都是java基本类型的,所以说嘛,在这里定义变量,你就想成是在java里定义就ok。

再来看看这几个TextView,第二个,我们直接使用@{str}来为android:text设置成上面定义个str的值,继续往下要注意了,我们使用了

android:text="@{String.valueOf(num)}"

来设置了一个int类型的变量,大家都知道我们在给android:text设置int类型的值时一定要转化为String类型,要不它就认为是资源文件了,这里我们还学到了一点,在xml中,我们不仅可以使用变量,而且还可以调用方法!

四、 变量定义的高级部分

在上面,我们学会了如何去在xml中定义变量,但是不知道你发现没?我们没有定义像ListMap等这样的集合变量。那到底能不能定义呢?答案肯定是可以的,而且定义的方式和我们上面的基本一致,区别就在于我们还需要为它定义key的变量,例如:

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <import type="org.loader.app2.Student" />
        <import type="android.graphics.Bitmap" />
        <import type="java.util.ArrayList" />
        <import type="java.util.HashMap" />
        <variable
            name="stu"
            type="Student" />
        <variable
            name="str"
            type="String"/>
        <variable
            name="error"
            type="boolean"/>
        <variable
            name="num"
            type="int" />
        <variable
            name="list"
            type="ArrayList&lt;String>" />
        <variable
            name="map"
            type="HashMap&lt;String, String>" />
        <variable
            name="array"
            type="String[]" />

        <variable
            name="listKey"
            type="int" />
        <variable
            name="mapKey"
            type="String" />
        <variable
            name="arrayKey"
            type="int" />
    </data>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{stu.name}"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{str}"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(num)}"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{list[listKey]}"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{map[`name`]}"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{array[0]}"/>
    </LinearLayout>
</layout>

这段代码比较长,但是我们仅关心那几个集合和数组,可以看到我们定义集合和定义普通变量一样,只不过这里我们还指定了一些的泛型,例如:ArrayList&lt;String>

下面我们还为下面使用这些集合准备了几个key,也都是变量。

继续看看怎么使用,和我们在java中使用不同,这里都是以:集合变量名[key]的形式使用,如果你的key是一个字面字符串可以使用反引号,也可以使用转义后的双引号。恩,这里也没有什么可以说的了,大家多看几遍就掌握了,都是概念性的东西,记住就ok。

五、在java代码中使用

前面定义了这么多变量,但是我们还没有给他们赋值!在哪赋值呢?肯定是在java代码中使用了,大部分情况我们还是在Activity中去使用它,以前我们都是在onCreate方法中通过setContentView去设置布局,但现在不一样了,现在我们是用过DataBindingUtil类的一个静态方法setContentView设置布局,同时该方法会返回一个对象,什么对象?这个对象有点特殊,它是一个自动生成的类的对象,看下面:

@Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       ActivityMainBinding binding = DataBindingUtil.setContentView(this,
               R.layout.activity_main);
    }

看到ActivityMainBinding了吗?就是它!那自动生成有什么规则了没?当然有了,记好了

将我们布局文件的首字母大写,并且去掉下划线,将下划线后面的字母大写,加上Binding组成。

看看上面的类,是不是符合这个规则。继续看看这个对象哪来的,是通过

DataBindingUtil.setContentView(this, R.layout.activity_main);

返回的,DataBindingUtil.setContentView的两个参数分别是当前Activity和布局文件。那接下来,就是我们关心的给变量赋值了。

@Override
protected void onCreate(Bundle savedInstanceState) {
   ...
    binding.setStu(new Student("loader"));
    binding.setStr("string");
    binding.setError(false);

    ArrayList<String> list = new ArrayList<String>() {
        {
            add("arraylist");
        }
    };
    binding.setList(list);
    binding.setListKey(0);

    HashMap<String, String> map = new HashMap<String, String>() {
        {
            put("name", "hashmap");
        }
    };
    binding.setMap(map);
//        binding.setMapKey("name");

    String[] array = new String[1];
    array[0] = "array";
    binding.setArray(array);
    binding.setArrayKey(0);
}

一连串的binding.setXXX,这个XXX是什么呢?就是我们在xml中定义的那些变量首字母大写了!也没好好说的吧,多看几遍。

六、 表达式

短暂的幸福时光,我们还是要告别java代码了,继续回到xml中,这一块,我们来学习一下表达式,什么?这玩意在xml中还支持表达式!

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text=‘@{error ? "error" : "ok"}‘/>

还记得上面我们定义了一个boolean的变量没有用到,这里我们就用到了,看好android:text,这里是一个三元表达式,如果error是true,则text就是error,否则是ok。这里还支持null合并操作,什么是null合并,相信看一眼你就知道了

android:text=‘@{str==null ?? "not null"}‘

简单解释一下,如果str是null,text的值就是str本身,否则就是”not null”。

它还支持一下表达式:

  • Mathematical + - / * %
  • String concatenation +
  • Logical && ||
  • Binary & | ^
  • Unary + - ! ~
  • Shift >> >>> <<
  • Comparison == > < >= <=
  • instanceof
  • Grouping ()
  • Literals - character, String, numeric, null
  • Cast
  • Method calls
  • Field access
  • Array access []
  • Ternary operator ?:

但是它不支持一下表达式:

  • this
  • super
  • new
  • Explicit generic invocation

七、 其他遗漏点

说到这里,xml中的事情基本算完了,但是还有几个小地方没有说,顺便说一下。

1. 设置别名

假如我们import了两个相同名称的类咋办?别怕,别名来拯救你!例如:

...
<data>
  <import type="xxx.Name" alias="MyName">
  <import type="xxx.xx.Name">
</data>
<TextView xxx:@{MyName.getName()}>
<TextView xxx:@{Name.getName()}>
...
  1. 自定义Binding名称

    还记得系统为我们生成好的那个binding类名吗?如果只能使用那样的是不是有点太暴力了?好在google对我们还算友好了,允许我们自定义binding名称,定制名称也很简单,就是给data一个class字段就ok。

    例如:

<data class=".Custom">
...
</data>

那么:DataBindingUtils.setContentView返回的binding类就是:你的应用包名.Custom

八、事件绑定

大家都知道,在xml中我们可以给button设置一个onClick来达到事件的绑定,现在DataBinding也提供了事件绑定,而且不仅仅是button

来看一下:

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <import type="org.loader.app3.EventHandlers" />
        <variable
            name="handlers"
            type="EventHandlers" />
    </data>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="CLICK ME"
            android:onClick="@{handlers.handleClick}"/>
    </LinearLayout>
</layout>

定义了一个EventHandlers类型的handlers变量,并在onClick的时候执行EventHandlershandleClick方法。

继续看看EventHandlers是怎么写的。

public class EventHandlers {
    public void handleClick(View view) {
        Toast.makeText(view.getContext(), "you clicked the view", Toast.LENGTH_LONG).show();
    }
}

很简单,就是简单的Toast了一下,这里要注意的是,handlerClick方法需要一个View的参数。

九、 数据对象

我们学会了通过binding为我们的变量设置数据,但是不知道你有没有发现一个问题,当我们数据改变的时候会怎样?数据是跟随着改变呢?还是原来的数据呢?这里告诉你答案:很不幸,显示的还是原来的数据?那有没有办法让数据源发生变化后显示的数据也随之发生变化?先来想想ListView是怎么做的, ListView的数据是通过Adapter提供的,当数据发生改变时,我们通过notifyDatasetChanged通过UI去改变数据,这里面的原理其实就是内容观察者,庆幸的是DataBinding也支持内容观察者,而且使用起来也相当方便!

BaseObservable

我们可以通过Observable的方式去通知UI数据已经改变了,当然了,官方为我们提供了更加简便的方式BaseObservable,我们的实体类只需要继承该类,稍做几个操作,就能轻松实现数据变化的通知。如何使用呢? 首先我们的实体类要继承BaseObservale类,第二步在Getter上使用注解@Bindable,第三步,在Setter里调用方法notifyPropertyChanged,第四步,完成。就是这么简单,下面我们来实际操作一下。

首先定义一个实体类,并继承BaseObservable

public class Student extends BaseObservable {
    private String name;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    @Bindable
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
        notifyPropertyChanged(org.loader.app4.BR.name);
    }
}

观察getName方法,我们使用了@Bindable注解,观察setName,我们调用了notifyPropertyChanged方法,这个方法还需要一个参数,这里参数类似于R.java,保存了我们所有变量的引用地址,这里我们使用了name。

再来看看布局文件。

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data class=".Custom">
        <import type="org.loader.app4.Student" />
        <variable
            name="stu"
            type="Student"/>
        <variable
            name="click"
            type="org.loader.app4.MainActivity" />
    </data>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="@{click.click}"
        android:text="@{stu.name}"/>
</layout>

不多说了,我们给TextView设置了文本,还有点击事件。Activity,

public class MainActivity extends AppCompatActivity {

    private Student mStu;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        org.loader.app4.Custom binding = DataBindingUtil.setContentView(this,
                R.layout.activity_main);
        mStu = new Student("loader");
        binding.setStu(mStu);
        binding.setClick(this);
    }

    public void click(View view) {
        mStu.setName("qibin");
    }
}

这段代码,首先显示的是loader,当我们点击TextView时,界面换成qibin。

ObservableFields家族

上面使用BaseObservable已经非常容易了,但是google工程师还不满足,继续给我们封装了一系列的ObservableFields,这里有ObservableFieldObservableBoolean,ObservableByte,ObservableChar,ObservableShort,ObservableInt,ObservableLong,ObservableFloat,ObservableDouble,ObservableParcelable

ObservableFields的使用方法就更加简单了,例如下面代码,

public class People {
    public ObservableField<String> name = new ObservableField<>();
    public ObservableInt age = new ObservableInt();
    public ObservableBoolean isMan = new ObservableBoolean();
}

很简单,只有三个ObservableField变量,并且没有getter和setter,因为我们不需要getter和setter。

在xml中怎么使用呢?

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data class=".Custom">

        <variable
            name="people"
            type="org.loader.app4.People" />
    </data>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{people.name}"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(people.age)}"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=‘@{people.isMan ? "man" : "women"}‘/>
    </LinearLayout>
</layout>

也很简单,直接使用变量,那怎么赋值和取值呢?这些ObservableField都会有一对getset方法,所以使用起来也很方便了:

...
mPeople = new People();
binding.setPeople(mPeople);
mPeople.name.set("people");
mPeople.age.set(19);
mPeople.isMan.set(true);
...

也不多说了。

Observable Collections

既然普通的变量我们有了ObservableFields的分装,那集合呢?当然也有啦,来看着两个:ObservableArrayMap,ObservableArrayList。使用和普通的Map、List基本相同,直接看代码:

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data class=".Custom">
        <variable
            name="map"
            type="android.databinding.ObservableArrayMap&lt;String,String>" />
        <variable
            name="list"
            type="android.databinding.ObservableArrayList&lt;String>" />
    </data>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{map[`name`]}"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{list[0]}"/>
    </LinearLayout>
</layout>

在布局中,使用方式和普通的集合一样,如果看不太懂,可以往上翻博客,看上面的集合是怎么使用的。

在来看java文件,怎么设置数据,

ObservableArrayMap<String, String> map = new ObservableArrayMap<>();
ObservableArrayList<String> list = new ObservableArrayList<>();
map.put("name", "loader or qibin");
list.add("loader!!!");
binding.setMap(map);
binding.setList(list);

哦,太简单了,简直和ListMap使用方法一模一样!!!

好了,不多说了,大家也都看累了吧。 那就先说到这里,其他的下篇博客我们继续学习。

demo源码下载,戳这里(稍等)

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-29 04:18:34

Android官方数据绑定框架DataBinding(一)的相关文章

Android官方数据绑定框架DataBinding

一.Data Binding是什么? 2015年的Google IO大会上,Android 团队发布了一个数据绑定框架(Data Binding Library),官方原生支持 MVVM 模型.以后可以直接在 layout 布局 xml 文件中绑定数据了,无需再 findViewById 然后手工设置数据了.其语法和使用方式和 JSP 中的 EL 表达式非常类似. Data Binding Library 是一个 support 库,支持 Android 2.1+ 版本 (API level 7

Android官方MVVM框架实现组件化之整体结构

一.google官方MVVM框架讲解 我前面对比了MVC和MVP<两张图看懂Android开发中MVC与MVP的区别>,可以相对于MVC我们的MVP是有多优越,但是Android开发现在已经开始流行了MVVM,前不久google官方发布了MVVM的正式库.官方的正式MVVM库主要包括下面四个: 其中只有ViewModel是MVVM结构中的一个组件,其他的三个都是辅助性质的. lifecycles 就是处理UI界面的生命周期,在26版本以后的Support库中,AppCompatActivity

基于Android官方Paging Library的RecyclerView分页加载框架

基于Android官方Paging Library的RecyclerView分页加载框架 我之前写了一篇RecyclerView分页加载机制的文章,是基于Android官方的AsyncListUtil实现的,详情见附录文章1.现在再介绍一种RecyclerView分页加载框架:Android Paging Library.Android Paging Library是Android官方support-v7支持包中专门做的分页框架,详细文档见谷歌官方文档附录2页面.我写这篇文章时候Paging L

Android兼容性测试框架(CTS)手册

了解老码农个人隐私,请看这里:http://www.koulianbing.com/?page_id=12 本文翻译自Android官方的CTS手册android-cts-manual-r4.pdf Android兼容性测试框架手册 1.为什么需要兼容性测试(以下称CTS)? 1.1.让APP提供更好的用户体验.用户可以选择更多的适合自己设备的APP.让APP更稳定. 1.2.让开发者设计更高质量的APP. 1.3.通过CTS的设备可以运行Androidmarket. 另外,CTS是免费的,而且

如何看待 Kotlin 成为 Android 官方支持开发语言?

"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 如何看待 Kotlin 成为 Android 官方支持开发语言? - Thinkblog - 博客频道 - CSDN.NET Thinkblog 爱编程,爱分享,不仅限于技术. 目录视图 摘要视图 订阅 [活动]2017 CSDN博客专栏评选 &nbsp [5月书讯]

【FastDev4Android框架开发】RecyclerView完全解析之结合AA(Android Annotations)注入框架实例(三十)

(一).前言: 话说RecyclerView已经面市很久,也在很多应用中得到广泛的使用,在整个开发者圈子里面也拥有很不错的口碑,那说明RecyclerView拥有比ListView,GridView之类控件有很多的优点,例如:数据绑定,Item View创建,View的回收以及重用等机制.本系列文章会包括到以下三个部分: RecyclerView控件的基本使用,包括基础,进阶,高级部分,动画之类(点击进入) RecyclerView控件的实战实例(点击进入) RecyclerView控件集合AA

如何看待 Kotlin 成为 Android 官方支持开发语言

Google IO 2017宣布了 Kotlin 会成为 Android 官方开发语言.一时间朋友圈和Android圈被各种刷屏.当然我也顺势而为发布了一篇的文章<为什么我要改用Kotlin>,着实狠狠地蹭了一波热度(尽管这样会被鄙视).眼下Android圈已经躁动了,甚至严重到如果对Kotlin视而不见就显得自己不像一个合格的Android程序员. 本文尝试从一个客观全面一点儿的角度来看待这件事情,尽力为大家提供一个比较理性的观点供参考. 为什么会选用Kotlin 关于 Google 为什么

Android代码内存优化建议-Android官方篇

转自:http://androidperformance.com/ http://developer.android.com/intl/zh-cn/training/displaying-bitmaps/index.html 为了使垃圾回收器可以正常释放程序所占用的内存,在编写代码的时候就一定要注意尽量避免出现内存泄漏的情况(通常都是由于全局成员变量持有对象引用所导致的),并且在适当的时候去释放对象引用.对于大多数的应用程序而言,后面其它的事情就可以都交给垃圾回收器去完成了,如果一个对象的引用不

Android官方开发文档Training系列课程中文版:目录

原文地址 : http://android.xsoftlab.net/training/index.html 引言 在翻译了一篇安卓的官方文档之后,我觉得应该做一件事情,就是把安卓的整篇训练课程全部翻译成英文,供国内的开发者使用,尤其是入门开发者,虽然现在网络上有很多入门课程,但是还是依靠官方文档学习来的靠谱,安卓官方文档是一系列的课程,使每个人可以系统的掌握安卓的知识,相比其它课程来说,它为开发者提供了查缺补漏的功能. 在这里你可以领略到安卓开发世界的精彩. Tips : 同时,本目录可以作为