Android(安卓)Architecture Components 部分源码代码分析
Android Architecture Components是Google发布的一套新的架构组件,使App的架构更加健壮
个人理解:如果理解有误请善待
简书链接:http://www.jianshu.com/p/1e57a4a5798d
依赖问题
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、ViewModelcompile "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 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 { 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() { @Override public void onChanged(@Nullable User user) { mTvAge.setText("年龄:"+user.age); } }); }}
上面代码中我在Activity中注册了了用户改变后的回调
这里findViewById 在 是26后习惯后,所以没有强转public 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 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() { @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- selected = new MutableLiveData
- (); public void select(Item item) { selected.setValue(item); } public LiveData
- 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 mNotCommittedActivityHolders = new HashMap<>();如果Activity是相同的就会返回相同的HolderFragment 而holderFramgent 内部又有ViewModelStore 实际应该还是相同的Activity才能有共享(猜测)
直到Activity或者Fragment销毁了,触发LifeCycle被销毁,那么ViewModel也会被销毁的。
Room
Room是SQL的提供了抽象层,实际和ORM差不多,便于开发
三个组成部分:
- DataBase:
- Entity:
- Dao
@Daopublic interface UserDao { @Query("SELECT * FROM user") List 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 abstractclass 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)
更多相关文章
- Android之浅谈activity生命周期
- android中handler 轮询数据变化 使用WeakReference防止内存泄露
- Android的数据存储之SharedPreferences1
- ContentProvider 详解
- android settings学习笔记(一)
- Android学习笔记-Intent(一)
- eclipse下开发android应用的几个常用插件
- Android(安卓)热补丁动态修复框架小结
- android红米等关于读取本地文件夹图片获取路径的问题的解决