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"

引入的场景

  1. 让开发者的关注点分离,举例:一个创建的问题是所有的代码写在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)

更多相关文章

  1. Android之浅谈activity生命周期
  2. android中handler 轮询数据变化 使用WeakReference防止内存泄露
  3. Android的数据存储之SharedPreferences1
  4. ContentProvider 详解
  5. android settings学习笔记(一)
  6. Android学习笔记-Intent(一)
  7. eclipse下开发android应用的几个常用插件
  8. Android(安卓)热补丁动态修复框架小结
  9. android红米等关于读取本地文件夹图片获取路径的问题的解决

随机推荐

  1. linux下android开发环境的配置
  2. android 开源项目集锦
  3. ubuntu android 调用 动态链接库
  4. Android布局优化
  5. android button 自定义
  6. Android Design版微信首度亮相:微信的一小
  7. Android之Android(安卓)Studio三种方式导
  8. Android图像处理技术(实现Android中的PS)(一
  9. Android点击WebView网页中的email发送邮
  10. Android 仿微信的键盘切换