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、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"

引入的场景

  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.(他是一个关于生命周期状态的组件,可以观察这个类)

enter image description here

一个状态一个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才能有共享(猜测)

enter image description here

直到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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值