Android Architecture Components
Android Architecture Components是Google发布的一套新的架构组件,使App的架构更加健壮
个人理解:如果理解有误请善待
原文链接:http://blog.csdn.net/qq_22329521/article/details/74231431
依赖问题
allprojects {
repositories {
jcenter()
//as支持从maven上下依赖库
maven { url 'https://maven.google.com' }
}
}
如果提示connect timeout相关的可以替换下
maven { url 'https://dl.google.com/dl/android/maven2/' }
给Android studio设置代理
http://blog.csdn.net/lchad/article/details/43567675
如果使用Lifecycle,LiveData、ViewModel
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"
如果使用Room(可以理解为为了持久化数据)
compile "android.arch.persistence.room:runtime:1.0.0-alpha1"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1"
// For Room RxJava support, add:
compile "android.arch.persistence.room:rxjava2:1.0.0-alpha1"
引入的场景
- 让开发者的关注点分离,举例:一个创建的问题是所有的代码写在Activity或者Fragment中,正常不处理UI操作的代码不放在Activity中的,后续提出了MVP和MVVM这些让Activity的重量不在加大,各个解耦,但是还是脱离不了因为生命周期的原因还是会在activity的代码中出现
//这是google中给的事例
class MyLocationListener {
public MyLocationListener(Context context, Callback callback) {
// ...
}
void start() {
// connect to system location service
}
void stop() {
// disconnect from system location service
}
}
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, (location) -> {
// update UI
});
}
//因为生命周期的关系,必须在相应的地方对她进行开启和关闭
public void onStart() {
super.onStart();
myLocationListener.start();
}
public void onStop() {
super.onStop();
myLocationListener.stop();
}
}
Lifecycle
Lifecycle:Lifecycle is a class that holds the information about the lifecycle state of a component (like an activity or a fragment) and allows other objects to observe this state.(他是一个关于生命周期状态的组件,可以观察这个类)

一个状态一个events 代码的应用
public class MyObserver implements LifecycleObserver {
public static String TAG="MyObery";
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void onResume(){
Log.e(TAG,"OnResume");
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void onPause(){
Log.e(TAG,"onPause");
}
}
public class MainActivity extends LifecycleActivity {
public static String TAG="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//这里MyObserver 与Activity 关联起来
getLifecycle().addObserver(new MyObserver());
}
}
MyObserver中的注解可以看出是生命周期回调的方法,这样就让MyObserver更在意他的逻辑,减少了Activity的代码
其中的类上面LifecycleObserver ,LifecycleActivity 以及getLifecycle()这个方法
- LifecycleObserver :注册观察者,在生命周期的注解中做相应的事情
- LifecycleActivity 实际就是FragmentActivity 实现了LifecycleRegistryOwner(LifecycleOwner) 和持有LifecycleRegistry 这个类(很神奇在于看上去是无侵入式的)
- getLifecycle()就是获取LifecycleRegistry 添加观察者
- 任何对象都可以变成LifecycleOwner实现内置 LifecycleRegistryOwner 接口(而不是延伸 LifecycleFragment 或 LifecycleActivity)。
内部源码实现
//这样就实现了生命周期的监听? 完全是无侵入的
public class LifecycleActivity extends FragmentActivity implements LifecycleRegistryOwner {
private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);
@Override
public LifecycleRegistry getLifecycle() {
return mRegistry;
}
}
public interface LifecycleRegistryOwner extends LifecycleOwner {
@Override
LifecycleRegistry getLifecycle();
}
LifecycleRegistry这个类 状态改变 做相应的处理,但是关键在于何处发出通知!!
public void handleLifecycleEvent(Lifecycle.Event event) {
if (mLastEvent == event) {
return;
}
mLastEvent = event;
mState = getStateAfter(event);
for (Map.Entry<LifecycleObserver, ObserverWithState> entry : mObserverSet) {
entry.getValue().sync();
}
}
首先想到的是可能是编译注解后再相应的生命周期回调发出通知,But 在app/build/intermediates/classes/debug/com..../xxxActivity 里面并没有生成相应的代码,到底是何处触发呢?,在提供的依赖文件中
最后在依赖的library的extensions-1.0.1-alpha3中找到LifecycleDispatcher和LifecycleRuntimeTrojanProvider这两个类
class LifecycleDispatcher {
static void init(Context context) {
//获取Application注册
((Application) context.getApplicationContext())
.registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
}
@SuppressWarnings("WeakerAccess")
@VisibleForTesting
static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {
private final FragmentCallback mFragmentCallback;
DispatcherActivityCallback() {
mFragmentCallback = new FragmentCallback();
}
//Activity创建的时候在出租回调注册其回调
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
if (activity instanceof FragmentActivity) {
//这里实际是给Actvity中的Fragment发送生命周期的消息
((FragmentActivity) activity).getSupportFragmentManager()
.registerFragmentLifecycleCallbacks(mFragmentCallback, true);
}
//这是个静态方法,在这里面
ReportFragment.injectIfNeededIn(activity);
}
@Override
public void onActivityStopped(Activity activity) {
if (activity instanceof FragmentActivity) {
markState((FragmentActivity) activity, CREATED);
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
if (activity instanceof FragmentActivity) {
markState((FragmentActivity) activity, CREATED);
}
}
}
.
.
.//
public class ReportFragment extends Fragment {
private static final String REPORT_FRAGMENT_TAG = "android.arch.lifecycle"
+ ".LifecycleDispatcher.report_fragment_tag";
public static void injectIfNeededIn(Activity activity) {
// ProcessLifecycleOwner should always correctly work and some activities may not extend
// FragmentActivity from support lib, so we use framework fragments for activities
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
//就注册一个ReportFragment
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
// Hopefully, we are the first to make a transaction.
manager.executePendingTransactions();
}
}
然后在当前ReportFragment的生命周期中发送
private void dispatch(Lifecycle.Event event) {
if (getActivity() instanceof LifecycleRegistryOwner) {
//handleLifecycleEvent这个就是上面LifecycleRegistry这个的昨天改变回调的方法
((LifecycleRegistryOwner) getActivity()).getLifecycle().handleLifecycleEvent(event);
}
}
LifecycleRuntimeTrojanProvider 这个类
public class LifecycleRuntimeTrojanProvider extends ContentProvider {
//就在onCreate 做初始化的操作,其他都不干,什么鬼?还是个ContentProvider
@Override
public boolean onCreate() {
LifecycleDispatcher.init(getContext());
//这个ProcessLifecycleOwner 内部向ReportFragment 注册了回调 ReportFragment 生命周期改变会 调用dispatch,同时还会调用ActivityInitializationListener 的回调方法,有点没太看懂 断点打在handleLifecycleEvent 确实会出现多次重复的生命周期
ProcessLifecycleOwner.init(getContext());
return true;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, String[] strings, String s, String[] strings1,
String s1) {
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, ContentValues contentValues) {
return null;
}
@Override
public int delete(@NonNull Uri uri, String s, String[] strings) {
return 0;
}
@Override
public int update(@NonNull Uri uri, ContentValues contentValues, String s, String[] strings) {
return 0;
}
}
对于ReportFragment 发送多次的问题先放着 至少实现了生命周期回调发送给观察者。然后是ContentProvider 在哪里调用 还是么找到!!! 最后在debug.apk 中找到!!! AS提供分析APK,Build下的Analyze Apk 查看编译后的debug.apk查看AndroidMainfest 多了这个
其中multiprocess 是true 是默认初始化,虽然还没找到什么时候插入到MainFest里面。
这个流程在于,AndroidMainFest中注册了LifecycleRuntimeTrojanProvider ,默认应用启动加载,初始化,然后在个Application注册Activity创建的回调,然后在回调中发送世界给观察者
LiveData
LiveData内部持有数据,当数据改变,可以通知ui做改变,还是和观察者差不多
public class UserLiveData extends MutableLiveData<User> {
public static String TAG="LocationLiveData";
private Context context;
private User user;
AppDataBase db;
public UserLiveData(final Context context) {
this.context=context;
}
@Override
protected void onActive() {
Log.e(TAG,"onActive");
runAge();
}
@Override
protected void onInactive() {
Log.e(TAG,"onInactive");
stopAge();
}
public STATE mState=STATE.Normal;
public enum STATE{
Start,
Stop,
Normal,
}
public void runAge(){
mState=STATE.Start;
new Thread(new Runnable() {
@Override
public void run() {
while (mState==mState.Start){
user.age=user.age+1;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
postValue(user);
}
}
}).start();
}
public void stopAge(){
mState=STATE.Stop;
}
}
public class MainActivity extends LifecycleActivity {
public static String TAG="MainActivity";
public TextView mTvAge;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTvAge=findViewById(R.id.tv_age);
UserLiveData user = new UserLiveData(this);
user.observe(this, new Observer<User>() {
@Override
public void onChanged(@Nullable User user) {
mTvAge.setText("年龄:"+user.age);
}
});
}
}
上面代码中我在Activity中注册了了用户改变后的回调
这里findViewById 在 是26后习惯后,所以没有强转
public <T extends View> T findViewById(int id){
}
LiveData 三个方法
- onActive():官方:This method is called when the LiveData has an active observer. This means we need to start observing the location updates from the device.(LiveData在被激活的状态下执行)。个人理解:google希望你在这里去做非初始化的操作例如,actvity 在初始化view后去做网络等数据,google可能希望onActive去做网络这些操作
- onInactive():This method is called when the LiveData does not have any active observers. (失去活性).个人理解:对象即将被消耗可以做些clear的操作
- setValue();当状态改变后回到onChanged
注意点:setValue必须在主线程中操作,我上面使用的MutableLiveData 实际MutableLiveData 继承了LiveData但是提供了postValue,这是内部使用主线程去做更新的任务,容易追踪代码,最后调用considerNotifyu去调用 observer.observer.onChanged((T) mData);
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
//检查是否是在主线程
private void assertMainThread(String methodName) {
if (!AppToolkitTaskExecutor.getInstance().isMainThread()) {
throw new IllegalStateException("Cannot invoke " + methodName + " on a background"
+ " thread");
}
}
ViewModel
ViewModel是用来存储UI层的数据,以及管理对应的数据,当数据修改的时候,可以马上刷新UI。
这里不是有了LiveData么,为什么还要有ViewModel, ViewModel出现,在于重新创建对象!!
举例
屏幕旋转是会销毁当前Activity的,然后重新加载数据,然后我们会在saveInstanceState中回复其数据,这种适合少量的数据,如果数据过大,就压力山大!!,而且往往会涉及到异步加载,网络重新请求相当于重新走oncreate,但是这并不属于我们开发者去管理这些工作,我们应该愉快的写代码,然后提供了ViewModel来管理数据
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTvAge=findViewById(R.id.tv_age);
if(savedInstanceState!=null){
//....
}else{
}
}
public class MyViewModel extends ViewModel {
public UserLiveData user;
public LiveData<User> getUser(Context context){
if (user==null) {
user = new UserLiveData(context);
}
return user;
}
}
public class MainActivity extends LifecycleActivity {
public static String TAG="MainActivity";
public TextView mTvAge;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTvAge=findViewById(R.id.tv_age);
MyViewModel myViewModel= ViewModelProviders.of(this).get(MyViewModel.class);
myViewModel.getUser(this).observe(this, new Observer<User>() {
@Override
public void onChanged(@Nullable User user) {
mTvAge.setText("年龄:"+user.age);
}
});
}
}
如果我们之前的做法 user的age是不断加1 ,如果旋转屏幕后,相当于重新new了user,age又是从0到1,但是现在 旋转屏幕后,user的age而是从刚才的位置依旧开始+1,内部ViewModelStore的hashmap维护了数据
共享数据改变
public class SharedViewModel extends ViewModel {
private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
public void select(Item item) {
selected.setValue(item);
}
public LiveData<Item> getSelected() {
return selected;
}
}
public class MasterFragment extends Fragment {
private SharedViewModel model;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {
model.select(item);
});
}
}
public class DetailFragment extends LifecycleFragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
model.getSelected().observe(this, { item ->
// update UI
});
}
}
上面代码么测试,但是猜测这种只能在同个Activity下才能发生(猜测),因为要确保两个Framgment中的SharedViewModel 是同一个对象
MyViewModel myViewModel= ViewModelProviders.of(this).get(MyViewModel.class);
//这里是主线程参见,这里必然会参见实体提供中,如果要提供相同的ViewModelStores
@MainThread
public static ViewModelProvider of(@NonNull FragmentActivity activity) {
initializeFactoryIfNeeded(activity.getApplication());
return new ViewModelProvider(ViewModelStores.of(activity), sDefaultFactory);
}
@MainThread
public static ViewModelStore of(FragmentActivity activity) {
//这个还是静态方法
return holderFragmentFor(activity).getViewModelStore();
}
最终会存放到
private Map<Activity, HolderFragment> mNotCommittedActivityHolders = new HashMap<>();
如果Activity是相同的就会返回相同的HolderFragment 而holderFramgent 内部又有ViewModelStore 实际应该还是相同的Activity才能有共享(猜测)

直到Activity或者Fragment销毁了,触发LifeCycle被销毁,那么ViewModel也会被销毁的。
Room
Room是SQL的提供了抽象层,实际和ORM差不多,便于开发
三个组成部分:
- DataBase:
- Entity:
- Dao
@Dao
public interface UserDao {
@Query("SELECT * FROM user")
List<User> getAll();
@Query("SELECT * FROM user where uid=:uid")
User getUser(long uid);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void updateUser(User users);
@Delete
void delete(User user);
}
@Entity(tableName = "user")
public class User {
@PrimaryKey
public long uid;
public String name;
public long age;
public User() {
uid= System.currentTimeMillis();
}
}
//数据库需要加载那些表
@Database(entities = {User.class},version = 1, exportSchema = false)
public abstract
class AppDataBase extends RoomDatabase{
public abstract UserDao userDao();
}
调用
AppDataBase db=Room.databaseBuilder(context,AppDataBase.class,"database-name").build();
db.userDao().updateUser(user);
api提供:https://developer.android.google.cn/topic/libraries/architecture/room.html
https://juejin.im/entry/591d41c70ce463006923f937
Room是为了持久化数据,写入数据库
不能主线程更新数据 ,会报错,可以使用RxJava或者AsyncTask来处理,google 的测试也只是在Junit来测试
以上都通过接口的形式,最终还是编译注解,在生成的class文件是可以找到生成的xxx_impl的文件,有兴趣可以看下
最后结合Drager2可以更好,来解决各个依赖。
参考文章
http://blog.csdn.net/guijiaoba/article/details/73692397(关于数据库挺详细的)
https://manijshrestha.wordpress.com/(kotlin结合的,也是在数据库中)
https://developer.android.google.cn/topic/libraries/architecture/adding-components.html(官网,翻墙)
https://github.com/googlesamples/android-architecture-components(推荐的demo)