Android Architecture Componets(Google官方提供的架构组件)
官网
https://developer.android.google.cn/topic/libraries/architecture/index.html
前言
Google 一直没有给Android 创建属于自己的官方架构方案,也没有官方确切的说支持MVP或者MVVM,反正什么样的架构代码的方式,Google一直都是包容的态度,在Github上也一直都有一个Android架构方案的开源项目。
2017 Google IO 虽然没有刻意去讨论Android,但是在Android Developer 网站上悄然出现了关于Android Architecture的东西,但并不是官方的架构方案,而是给出了一个可选的架构方案。
架构方案
Android Architecture Componets 组件
组件 | 说明 | url |
---|---|---|
Lifecycle | 有点像RxLifecycler的处理方式,监听生命周期中的事件 | https://developer.android.google.cn/topic/libraries/architecture/lifecycle.html |
LiveData | 使用观察者模式,用于观察数据返回,用过RxJava的都会觉得眼熟,可以替代部分RxJava的功能 | https://developer.android.google.cn/topic/libraries/architecture/livedata.html |
ViewModel | 在架构方案中,用于实现ViewModel层,同时默认绑定Lifecycle,生命周期可以使用Lifcycle中的生命回调来控制,可以脱离Activity或Fragment,在ViewModel中处理响应UI生命周期函数。 | https://developer.android.google.cn/topic/libraries/architecture/viewmodel.html |
Room | 官方 Sqlite ORM库 | https://developer.android.google.cn/topic/libraries/architecture/room.html |
架构方案代码演示
ViewModel demo
//继承ViewModel 在新推荐的架构方案中与Ui层进行逻辑分离
public class UserProfileViewModel extends ViewModel {
private String userId;
private LiveData<User> user;
public void init(String userId) {
this.userId = userId;
}
//使用 LiveData 包装 真实的Model对象
public LiveData<User> getUser() {
return user;
}
}
UI 层使用 ViewModel
//需要继承新的LifecycleFragment类,该类是Fragment的子类,但是该类实现了LifecycleOwner接口
public class UserProfileFragment extends LifecycleFragment {
private static final String UID_KEY = "uid";
private UserProfileViewModel viewModel;
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String userId = getArguments().getString(UID_KEY);
//获取ViweModel
viewModel = ViewModelProviders.of(this).get(UserProfileViewModel.class);
//滴啊用ViewModel中的业务方法
viewModel.init(userId);
//使用LiveData方式获取User信息
viewModel.getUser().observe(this, user -> {
// update UI
});
}
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.user_profile, container, false);
}
}
Repository
//User Dagger2 DI
@Singleton
public class UserRepository {
private final Webservice webservice;
private final UserDao userDao;
private final Executor executor;
@Inject
public UserRepository(Webservice webservice, UserDao userDao, Executor executor) {
this.webservice = webservice;
this.userDao = userDao;
this.executor = executor;
}
public LiveData<User> getUser(String userId) {
refreshUser(userId);
// return a LiveData directly from the database.
return userDao.load(userId);
}
private void refreshUser(final String userId) {
executor.execute(() -> {
// running in a background thread
// check if user was fetched recently
boolean userExists = userDao.hasUser(FRESH_TIMEOUT);
if (!userExists) {
// refresh the data
Response response = webservice.getUser(userId).execute();
// TODO check for error etc.
// Update the database.The LiveData will automatically refresh so
// we don't need to do anything else here besides updating the database
userDao.save(response.body());
}
});
}
}
WebService
//Retrofit 2 网络请求
public interface Webservice {
/**
* @GET declares an HTTP GET request
* @Path("user") annotation on the userId parameter marks it as a
* replacement for the {user} placeholder in the @GET path
*/
@GET("/users/{user}")
Call<User> getUser(@Path("user") String userId);
}
Room 持久化数据
Entity
@Entity
class User {
@PrimaryKey
private int id;
private String name;
private String lastName;
// getters and setters for fields
}
Dao
@Dao
public interface UserDao {
@Insert(onConflict = REPLACE)
void save(User user);
@Query("SELECT * FROM user WHERE id = :userId")
LiveData<User> load(String userId);
}
RoomDatabase
@Database(entities = {User.class}, version = 1)
public abstract class MyDatabase extends RoomDatabase {
public abstract UserDao userDao();
}
依赖
项目根路径下的build.gradle 新增一下仓库
allprojects {
repositories {
jcenter()
maven { url 'https://maven.google.com' }
}
}
依赖
//For Lifecycles, LiveData, and ViewModel, add:
compile "android.arch.lifecycle:runtime:1.0.0-alpha1"
compile "android.arch.lifecycle:extensions:1.0.0-alpha1"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha1"
//For Room, add:
compile "android.arch.persistence.room:runtime:1.0.0-alpha1"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1"
已知限制和问题
- 测试版本的 Lifecycle Fragment 和ActivityCompat 在Support Library 中并没有实现LifecycleOwner 接口,在正式版1.0.0发布时,将正确实现。