implementation 'androidx.appcompat:appcompat:1.0.0'
def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
def lifecycle_version = "2.2.0"
def arch_version = "2.1.0"
implementation "androidx.recyclerview:recyclerview:1.1.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// Annotation processor
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// optional - helpers for implementing LifecycleOwner in a Service
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
没什么好说的,这些基本上是迁移androidx 需要的库,你要把项目中的appcomt 库的引用去掉。
compileSdkVersion 28
提升编译版本,因为有些androidx 的依赖库只能在28上。
androidx.fragment.app.Fragment
fragment 只是举例的一个类而已,有挺多类的,比如AppCompatActivty…
只要是替换成androidX 找不到的类,基本上都要换路径。
package com.example.viewModel;
import com.example.database.UserDBManager;
import com.example.rom.UseDao;
import com.example.rom.User;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
/**
* =======================================================================================
* 作 者:caoxinyu
* 创建日期:2020/3/20.
* 类的作用:
* 修订历史:
* =======================================================================================
*/
public class UserViewModel extends ViewModel {
private MutableLiveData> users;
public LiveData> getUsers() {
if (users == null) {
users = new MutableLiveData<>(new ArrayList<>());
}
final List value = users.getValue();
Thread thread = Executors.defaultThreadFactory().newThread(new Runnable() {
@Override
public void run() {
UseDao useDao = UserDBManager.getInstance().getUseDao();
List usersAll = useDao.queryAll();
if (value != null) {
value.addAll(usersAll);
}
users.postValue(value);
}
});
thread.start();
return users;
}
}
ViewModel 是和activity 生命明周期绑定的一个类,里面一般有个字段,是LiveData,就像我上面写的一样。
一般获取方式为:
UserModel userModel = new ViewModelProvider(requireActivity()).get(UserModel.class);
具体可以看上面贴出来的类。
首先在xml 最外加 标签,里面的 可以对应你写的ViewModel
databing 在xml 的具体写法,可以百度看下,这里先不贴了。挺多种的,或者有时间我写一篇。
// Inflate the layout for this fragment
FragmentRoomTestBinding fragmentRoomTestBinding = FragmentRoomTestBinding.inflate(inflater, container, false);
UserViewModel userViewModel = new ViewModelProvider(this).get(UserViewModel.class);
fragmentRoomTestBinding.setAddUser(new View.OnClickListener() {
@Override
public void onClick(View v) {
UserDBManager.getInstance().insertTestUser();
userViewModel.getUsers();
}
});
LiveData> users = userViewModel.getUsers();
mUserList = new ArrayList<>();
List userList = users.getValue();
if (userList != null) {
mUserList.addAll(userList);
}
RecyclerView recycleView = fragmentRoomTestBinding.recycleView;
recycleView.setLayoutManager(new LinearLayoutManager(getContext()));
UserAdapter adapter = new UserAdapter(mUserList, BR.itemInfo);
fragmentRoomTestBinding.setUserIsEmpty(mUserList.isEmpty());
users.observe(this, new Observer>() {
@Override
public void onChanged(List users) {
mUserList.clear();
mUserList.addAll(users);
adapter.notifyDataSetChanged();
fragmentRoomTestBinding.setUserIsEmpty(users.isEmpty());
}
});
recycleView.setAdapter(adapter);
当我的liveData 更新之后,如果是在子线程更新的,那么回调的时候,框架是怎么切换到主线程的?
ViewDataBing 里面有两种方法: ViewDataBing 的时候,生成一个handler 保存一下。 mUIThreadHandler = new Handler(Looper.myLooper()); 需要用的时候用handler postRunable 就可以解决
第二种是 Choreographer,这个是databing 默认的方式:
mChoreographer = Choreographer.getInstance();
mFrameCallback = new Choreographer.FrameCallback() {
@Override
public void doFrame(long frameTimeNanos) {
mRebindRunnable.run();
}
};
mChoreographer.postFrameCallback(mFrameCallback);
androidx.databinding.ViewDataBinding.LiveDataListener
/**
* Method object extracted out to attach a listener to a bound LiveData object.
*/
private static final CreateWeakListener CREATE_LIVE_DATA_LISTENER = new CreateWeakListener() {
@Override
public WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) {
return new LiveDataListener(viewDataBinding, localFieldId).getListener();
}
};
你会看到,androidx.databinding.ViewDataBinding
这个类里面,CREATE_LIVE_DATA_LISTENER 会给所有的ViewMode 里面的LiveData 对象 设置一个监听,当ViewModel 里面的LiveData 对象的值,变化了,那么databinding 就会更新UI.
3.根据xml 生成的dataBing在哪里?
会有两个,一个是基础类,叫做bind,一个叫做impl.基本上更新UI的代码,都在impl里面。executeBindings 方法会真正的调用绑定,比如TextView. setText