Andorid 状态管理之Lifecycle浅析

目录
  • 原理概述
  • 构成
  • 模型
  • 源码
    • 1. addObserver(observer)
    • 2. sync()
    • 3. setCurrentState、moveToState
  • 监听
  • 其他
    • 1. Application.ActivityLifecycleCallbacks
  • 总结

原理概述

Lifecycle主要用于Activity、Fragment这一类具有状态的组件的状态监听,最主要的一个作用就是将原先Activity、Fragment中的大量的生命周期相关的回调函数移出View层文件,从设计角度上来说,使得MVVM中的View层文件的结构更加清晰、简单,简化了View层的任务,使得代码更清晰、易于维护。

Lifecycle实现监听的原理主要有两种方式,在API29以下的版本主要采用的是方法一,而在API29+的版本采用的是方法二。

  • 和Glide插件一样的,采用一个专门用于报告状态的Fragment,当这个特殊的空白Fragment被插入到宿主Activity时,就可以获取到宿主的生命周期状态改变。
  • 实现Application.ActivityLifecycleCallbacks,监听相关的生命周期的改变。

大概的使用步骤如下:

  • 声明自己的监听组件:MyUtil实现LifecycleObserver接口
  • 采用注解声明生命周期回调函数:
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    private void fun1(){
        //on_create时需要做的事情
    }

在MainActivity.java中调用:

getLifecycle().addObserver(new MyUtil());

显然,在这个模型中,lifecycle本身只是一个事件的源头,而我们自己实现的监听者MyUtil则是观察者,我们像lifecycle注册我们的工具,一旦lifecycle收到了生命周期的变化通知,那么就通知一系列的观察者进行更新:

Lifecycle本身更像是一个代理,我们的工具类不需要自己去做监听这一件事情了,所以这实际上可以看做是两个观察者模式的合成,而中间的lifecycle是一个系统为我们提供的接口,用于获得回调。我们只需要注册我们的Observer即可。这样一来,分析lifecycle的过程明显被拆成了两个子问题:

问题1. MyUtil(LifecycleObserver)是如何监听lifecycle的?

问题2. lifecycle是如何监听宿主(LifecycleOwner)生命周期变化的?

构成

Lifecycle的构成对象:

  • Lifecycle:即生命周期,某个组件(Activity、Fragment)可能会具有自己的Lifecycle。
  • LifecycleOwner:Lifecycle的持有者,某个组件(Activity、Fragment)。
  • LifecycleObserver:即观察者,我们需要对某个组件的生命周期进行观察,那么就必须实现LifecycleObserver,通过lifecycle的addObserver方法对LifecycleObserver进行注册监听,这样一来对应的LifecycleObserver的类就能够得到生命周期的相关回调了。
  • Event:即生命周期回调的方法,例如ON_CREATE、ON_START等等。
  • State:当某个Event发生后,会导致State的转变,例如ON_CREATE事件发生时,State将会从INITIALIZED走向CREATED,如下【模型】中的状态转移关系图。
    • INITIALIZED:刚刚被初始化。
    • CREATED:ON_CREATE之后、ON_STOP之后。
    • STARTED:ON_START之后、ON_PAUSE之后。
    • RESUMED:ON_RESUME之后、ON_PAUSE之前
    • ON_DESTORYED:ON_DESTROY之后,还未被创建或者已经销毁。

模型

//对应的状态转移函数
@NonNull
public State getTargetState() {
  	//枚举类,this标识的是某种事件,例如ON_CREATE、ON_STOP等等。
    switch (this) {
        //对于ON_CREATE和ON_STOP事件,都对应CREATED状态。(图上二者都指向CREATED)
        case ON_CREATE:
        case ON_STOP:
            return State.CREATED;
        case ON_START:
        case ON_PAUSE:
            return State.STARTED;
        case ON_RESUME:
            return State.RESUMED;
        case ON_DESTROY:
            return State.DESTROYED;
        case ON_ANY:
            break;
    }
    throw new IllegalArgumentException(this + " has no target state");
}

源码

1. addObserver(observer)

LifecycleOwner作为事件的源头,Fragment、Activity都是LifecycleOwner。换句话说就是这两者会产生一些列生命周期相关的事件。

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        LifecycleOwner

LifecycleOwner提供了唯一一个方法,并且,在ComponentActivity类中,使用的是Lifecycle的一个实现类:mLifecycleRegistry

public interface LifecycleOwner {
    @NonNull
    Lifecycle getLifecycle();
}
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
//LifecycleRegistry.java
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
    enforceMainThreadIfNeeded("addObserver");//主线程断言
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;//如果mState是已经销毁的则就标记为已经销毁;如果是其他的(所有有效的),就标记为已初始化过的。
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);//传入自定义的观察者(非被观察者)和状态。
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);//尝试放入被观察者维护的观察者对象集合中(如果不存在的话,防止多次注册)。如果存在,返回既有值的value;如果不存在put,并返回null。
  	//如果之前存在一个相同的observer,那么直接return;
    if (previous != null) {
        return;
    }
  	//取得lifecycleOwner对象,通常是Activity或者是Fragment,注意,此处的LifecycleOwner是被WeakReference<LivecycleOwner>引用住的。是在LifecycleRegistry的构造函数中,被注入了值。
   	//private final WeakReference<LifecycleOwner> mLifecycleOwner;

    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();

  	//如果为空,说明对象已经被回收了,return掉。
    if (lifecycleOwner == null) {
        // it is null we should be destroyed. Fallback quickly
        return;
    }

    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
    State targetState = calculateTargetState(observer);
    mAddingObserverCounter++;
		//正在注册的观察者数量+1

  	//ENUM Class之间的比较,二者相等会返回0。这个循环作用就是追加之前的生命周期事件派发(粘性)
    while ((statefulObserver.mState.compareTo(targetState) < 0
            && mObserverMap.contains(observer))) {
      	//该行代码的内部实现是:mParentStates.add(state);其中的mParentStates是一个ArrayList,用于存储一些“旧”的消息。例如我们在running(create、start、resume都走完了)状态通过点击按钮注册一个监听,此时的pushParentState中的参数:statefulObserver.mState就是“INITIALIZED”。
        pushParentState(statefulObserver.mState);
      	//接着上面的情况,传入的参数是:INITIALIZED,从upFrom中取出的Event是“ON_CREATE”,但是此时onCreate状态实际上早已走完了。
        final Event event = Event.upFrom(statefulObserver.mState);
        if (event == null) {
            throw new IllegalStateException("no event up from " + statefulObserver.mState);
        }
      	//注意,我们在实例中的ON_CREATE等等回调都是在这步里面执行的【图1】,主要是更新状态,和派发事件,走完这代码,statefulObserver.mState就变成了CREATED
        statefulObserver.dispatchEvent(lifecycleOwner, event);

      	//和pushParentState对应,此时删除后parentState长度为0。
        popParentState();

        targetState = calculateTargetState(observer);
      	//此时statefulObserver.mState为CREATED,而targetState的值被更新为:RESUME。
    }

    if (!isReentrance) {
        // we do sync only on the top level.
        sync();
    }
    mAddingObserverCounter--;
}

接下来的第二轮代码的,其实和第一轮类似,就是从Event从ON_CREATE变成了ON_START,然后派发了ON_START事件。ON_RESUME同理。大概的流程是,添加Observer的时候。以statefulObserver为主,不论Activity是什么状态,进入时initialState都是INITIALIZED状态,然后利用Event.upFrom函数,根据状态(State,例如CREATED),取出事件(Event,例如ON_CREATE),然后, statefulObserver.dispatchEvent(lifecycleOwner, event);更新了statefulObserver的状态,依次类推。

以上代码的几个比较关键的展开:

private State calculateTargetState(LifecycleObserver observer) {

  	//mObserverMap即上面addObserver主干代码中的第七行:
  	//ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
  	//此处是对该Map唯一的加入调用。

  	//取出临近的ObserverWithState,FastSafeIterableMap,注释中说是:Poor's man LinkedHashMap
  	//LifecycleObserver在androidx.core.app.ComponentActivity中可以看到,ComponentActivity实现了该接口。
  	//所以,该Map是一个Activity对应ObserverWithState(一个State、一个LifecycleEventObserver)的结构:

    Map.Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);

  	//如果不为空,那么就设置siblingState为previous中存储对象的mState else null
    State siblingState = previous != null ? previous.getValue().mState : null;
  	//如果有parentState,那么获取其中的最后一个的State else null
    State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
            : null;
  	//取mState、siblingState和parentState中最小值。
    return min(min(mState, siblingState), parentState);
}

//statefulObserver.dispatchEvent(lifecycleOwner, event);
void dispatchEvent(LifecycleOwner owner, Event event)
   //根据event(ENUM)获取其状态,这个和上面的状态图是一样的。
   State newState = event.getTargetState();
	 //取最小状态
   mState = min(mState, newState);
   //更新状态,响应回调
   mLifecycleObserver.onStateChanged(owner, event);
	 //设置新状态
   mState = newState;
}

2. sync()

private void sync() {
  	//即Activity、Fragment这类生命周期持有者。
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
  	//判断是否已经被回收
    if (lifecycleOwner == null) {
        throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
                + "garbage collected. It is too late to change lifecycle state.");
    }
  	//如果mObserverMap中的元素还没有完全同步就进行循环,进行所有保存着的观察者的状态同步。
    while (!isSynced()) {
      	//标记是否有新的事件出现,当moveToState被调用时,满足条件(mHandlingEvent || mAddingObserverCounter != 0)时,该属性会被置为true。
      	//这两个条件是:1是否正在处理事件,2是是否正在处理新加入的观察者。
        mNewEventOccurred = false;
        //利用mState和mObserverMap中最老的元素状态相比较,如果更小(最小的是DESTROY,INITIALIZED,一直到RESUMED),那么久从最早被加入的元素,顺着这个LinkedHashMap进行后向的更新。例如CREATED < RESUMED
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
          	//后向传播
            backwardPass(lifecycleOwner);
        }
        Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
      	//如果没有新的事件出现(期间没有moveToState被触发),最新的观察者不为空,并且有当前组件的状态更先于最新组件的状态。
      	//例如mState = RESUMED和newest.mState = CREATED,那么就触发前向传播。
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
          	//前向传播
            forwardPass(lifecycleOwner);
        }
      	//在这个循环中,直到所有Observer状态全部同步为止。
    }
    mNewEventOccurred = false;
}

private boolean isSynced() {
  	if (mObserverMap.size() == 0) {
    	return true;
  	}
  	State eldestObserverState = mObserverMap.eldest().getValue().mState;
  	State newestObserverState = mObserverMap.newest().getValue().mState;
  	//判断最晚加入的 是否等于 最早加入的 是否等于 当前的状态。
  	return eldestObserverState == newestObserverState && mState == newestObserverState;
}
//forwardPass同理;
private void backwardPass(LifecycleOwner lifecycleOwner) {
  	//迭代器
    Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
            mObserverMap.descendingIterator();
  	//在forwardPass中:
    //Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
    //			mObserverMap.iteratorWithAdditions();
  	//在没有新的事件(moveToState触发)的情况下进行迭代。
    while (descendingIterator.hasNext() && !mNewEventOccurred) {
        Map.Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
        ObserverWithState observer = entry.getValue();
        while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
          	//和addObserver中相似的逻辑,同步时主动去回调其他滞后的监听者的状态。
            Event event = Event.downFrom(observer.mState);
            if (event == null) {
                throw new IllegalStateException("no event down from " + observer.mState);
            }
            pushParentState(event.getTargetState());
            observer.dispatchEvent(lifecycleOwner, event);
            popParentState();
        }
    }
}

3. setCurrentState、moveToState

这一类的方法用于外部调用,用于lifecycle的状态转移。例如我们可以显式地在一个Activity的所有生命周期中,调用setCurrentState方法来标记(通知)lifecycle状态。标记完成后,将触发sync进行所有观察者状态的同步。

    @MainThread
    public void setCurrentState(@NonNull State state) {
        enforceMainThreadIfNeeded("setCurrentState");//断言主线程
        moveToState(state);
    }

    /**
     * Sets the current state and notifies the observers.
     * <p>
     * Note that if the {@code currentState} is the same state as the last call to this method,
     * calling this method has no effect.(如果在相同的State下调用此方法无效。)
     *
     * @param event The event that was received
     */
    public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        enforceMainThreadIfNeeded("handleLifecycleEvent");//断言主线程
        moveToState(event.getTargetState());
    }

    private void moveToState(State next) {
      	//相同状态下调用无效。
        if (mState == next) {
            return;
        }
        mState = next;
      	//如果正在处理事件,或者含有某个刚刚加入的Observer(数量不为0),那么久标记当前有新的事件出现了。
        if (mHandlingEvent || mAddingObserverCounter != 0) {
            mNewEventOccurred = true;
            // we will figure out what to do on upper level.
            return;
        }
        mHandlingEvent = true;//标记正在处理事件,有点像锁
        sync();//同步(前后向传播)
        mHandlingEvent = false;//结束
    }

监听

从moveToState说起,它有三个调用。

@Deprecated
@MainThread
public void markState(@NonNull State state) {
    enforceMainThreadIfNeeded("markState");
    setCurrentState(state);
}

@MainThread
public void setCurrentState(@NonNull State state) {
    enforceMainThreadIfNeeded("setCurrentState");
    moveToState(state);
}
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
    enforceMainThreadIfNeeded("handleLifecycleEvent");
    moveToState(event.getTargetState());
}

markState已经被标记为@Deprecated,但是我们可以找到它的一个调用:package androidx.core.app下的ComponentActivity中的onSaveInstanceState仍然保持着这个方法的调用。

package androidx.core.app;

@CallSuper
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    mLifecycleRegistry.markState(Lifecycle.State.CREATED);//
    super.onSaveInstanceState(outState);
}

setCurrentState则在package androidx.activity;中的ComponentActivity被引用:

package androidx.activity;

@CallSuper
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    Lifecycle lifecycle = getLifecycle();
    if (lifecycle instanceof LifecycleRegistry) {
        ((LifecycleRegistry) lifecycle).setCurrentState(Lifecycle.State.CREATED);//
    }
    super.onSaveInstanceState(outState);
    mSavedStateRegistryController.performSave(outState);
}

至于handleLifecycleEvent:

很明显在AppcompatActivity中,handleLifecycleEventlifecyle的关系比较密切。

例如,在onCreate方法中,有:

    protected void onCreate(@Nullable Bundle savedInstanceState) {
        mFragments.attachHost(null /*parent*/);

        if (savedInstanceState != null) {
           //如果是重建的Activity进行的操作,以下省略
           ......
        }

        if (mPendingFragmentActivityResults == null) {
            mPendingFragmentActivityResults = new SparseArrayCompat<>();
            mNextCandidateRequestIndex = 0;
        }

        super.onCreate(savedInstanceState);

        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);//派发事件
        mFragments.dispatchCreate();
    }

每当我们的Activity父类的FragmentActivity的方法:onCreate被回调时,必然会触发handleLifecycleEvent()的执行,这样一来非常简单地就实现了监听。

但是,在androidx.activity.ComponentActivity;中,有一段非常特殊的代码:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mSavedStateRegistryController.performRestore(savedInstanceState);
    ReportFragment.injectIfNeededIn(this);//
    if (mContentLayoutId != 0) {
        setContentView(mContentLayoutId);
    }
}
public static void injectIfNeededIn(Activity activity) {
    if (Build.VERSION.SDK_INT >= 29) {
        // On API 29+(Android 10.0 +), 我们可以直接注册正确的lifecycle监听,内部将会直接实现监听:在Activity类中的mActivityLifecycleCallbacks中,加入一个Callback:mActivityLifecycleCallbacks.add(callback);
        activity.registerActivityLifecycleCallbacks(
                new LifecycleCallbacks());
    }

    android.app.FragmentManager manager = activity.getFragmentManager();
    if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
      	//注意这里,我们向当前的Activity中新加入了一个new ReportFragment()。
        manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
        manager.executePendingTransactions();
    }
}

任取一个Fragment的生命周期函数作为观察,进入dispatch()方法。

@Override
public void onStart() {
    super.onStart();
    dispatchStart(mProcessListener);
    dispatch(Lifecycle.Event.ON_START);
}

@Override
public void onResume() {
    super.onResume();
    dispatchResume(mProcessListener);
    dispatch(Lifecycle.Event.ON_RESUME);
}

@Override
public void onPause() {
    super.onPause();
    dispatch(Lifecycle.Event.ON_PAUSE);
}

在dispatch方法中,发现将activity当做LifecycleOwner获取了其Lifecycle进行事件的处理。

@SuppressWarnings("deprecation")
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
    if (activity instanceof LifecycleRegistryOwner) {
        ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);//
        return;
    }

    if (activity instanceof LifecycleOwner) {
        Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
        if (lifecycle instanceof LifecycleRegistry) {
            ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);//
        }
    }
}

其中,LifecycleRegistryOwner是LifecycleOwner接口的子类,可以看到返回值不同。显然,当Activity生命周期发生变动时,Fragment的生命周期也会相应地发生变动,由ReportFragment的生命周期函数中进行handleLifecycleEvent就非常巧妙地实现了监听这一功能。这一点和Glide的实现(采用一个空白的RequestManagerFragment)非常相似。

但是,在API29+,程序会走这样一段代码:

public static void injectIfNeededIn(Activity activity) {
    if (Build.VERSION.SDK_INT >= 29) {
        // On API 29+, we can register for the correct Lifecycle callbacks directly
        LifecycleCallbacks.registerIn(activity);
    }
    //……
}

static class LifecycleCallbacks implements Application.ActivityLifecycleCallbacks {

  	//有做省略
    static void registerIn(Activity activity) {
        activity.registerActivityLifecycleCallbacks(new LifecycleCallbacks());
    }
    @Override
    public void onActivityPostCreated(@NonNull Activity activity,
            @Nullable Bundle savedInstanceState) {
        dispatch(activity, Lifecycle.Event.ON_CREATE);
    }
    @Override
    public void onActivityPostStarted(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_START);
    }
    @Override
    public void onActivityPostResumed(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_RESUME);
    }
    @Override
    public void onActivityPrePaused(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_PAUSE);
    }
    @Override
    public void onActivityPreStopped(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_STOP);
    }
    @Override
    public void onActivityPreDestroyed(@NonNull Activity activity) {
        dispatch(activity, Lifecycle.Event.ON_DESTROY);
    }
}

同时,Api29+的机型,也会走到:插入一个ReportFragment。理论上,通过Application.ActivityLifecycleCallbacks 回调就已经能够注册到监听了,至于为什么这么设计并不清楚。但是到派发事件时的dispatch方法:

private void dispatch(@NonNull Lifecycle.Event event) {
    if (Build.VERSION.SDK_INT < 29) {
        dispatch(getActivity(), event);//TAG
    }
}

它限制了通过Fragment生命周期回调产生的监听只在Api<29才会进行派发,所以不会产生两次派发。而标记的TAG处的dispatch是一个静态方法,注意,API29+的dispatch直接就是调用的这个静态方法。

static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
    if (activity instanceof LifecycleRegistryOwner) {
        ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
        return;
    }

    if (activity instanceof LifecycleOwner) {
        Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
        if (lifecycle instanceof LifecycleRegistry) {
            ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
        }
    }
}

//API29中的调用,走的是上面的静态方法。
@Override
public void onActivityPostStarted(@NonNull Activity activity) {
	  dispatch(activity, Lifecycle.Event.ON_START);
}

不论是API29以下通过Fragment监听,还是API29以上,通过Application.ActivityLifecycleCallbacks进行监听,走的都是lifecycle.handleLifecycleEvent()方法。这也是为什么在上文中提handleLifecycleEvent有大量调用的调用:

其他

1. Application.ActivityLifecycleCallbacks

该接口含有大量的回调函数,和日常开发中的那三对回调函数不同,这里的划分更加细致,有三组,并且每组又区分pre和post,外加一个onActivitySaveInstanceState,每当Activity发生生命周期转变时,该回调函数都会被回调到,并且参数是发生变化的Activity。我们可以自定义一个类实现该接口,然后this.registerActivityLifecycleCallbacks(callbacks);注册一下即可。该类还可以实现更灵活的Activity 实例数量管控。大部分的事件都是在POST部分中处理的,而不是Pre。

@Override
public void onActivityResumed(@NonNull Activity activity) {
}
@Override
public void onActivityPostResumed(@NonNull Activity activity) {
    dispatch(activity, Lifecycle.Event.ON_RESUME);//向监听者(MyUtils类等等)派发事件
}

总结

从监听开始,在API29以下的版本中,会向Activity中加入一个ReportFragment,该Fragment的生命周期发生变化时,将会进行派发时间,更新lifecycle的生命周期,再由Lifecycle统一通知LifecycleObserver生命周期更新;而API29+,则会直接通过监听Application.ActivityLifecycleCallbacks接口,进行获取Activity的状态,同时也会插入ReportFragment,但是该用于报告状态的Fragment的生命周期中的dispatch将不会生效,Fragment和Activity都添加一个监听,并在onStop前后添加输出,两种方式(API29+和API29以下)的回调顺序也是不同的。

到此这篇关于Andorid 状态管理之Lifecycle浅析的文章就介绍到这了,更多相关Andorid Lifecycle 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Andorid 日历控件库,可左右滑动,显示公历,农历,节假日等功能

    封面图:  demo效果图 源码目录结构         Features 日历左右滑动. 显示阳历,农历,节假日和二十四节气 实现对某月日期的单选或者多选. 使用步骤 Gradle Dependency Add the library to your project build.gradle compile 'com.joybar.calendar:librarycalendar:1.0.4' Sample Usage 实现OnPageChangeListener和OnDateClickLis

  • andorid 使用手势监听器GestureDetector遇到的不响应问题

    做了一个项目,首页是使用ResideMenu实现,通过菜单栏里的菜单项创建的Fragment:所以一个Activtiy里就包含多个Fragment,想通过手势也能侧滑,就不用点击菜单按钮打开menu了: 方法如下: 在activity的oncreate()中初始化手势监听器 mGestureDetector = new GestureDetector(getApplicationContext(), new MyGestureListener(getApplicationContext()));

  • Andorid jar库源码Bolts原理解析

    Bolts: 作用: 用于链式执行跨线程代码,且传递数据 栗子: 复制代码 Task.call(new Callable<Boolean>() { @Override public Boolean call() throws Exception { return true; } }, Task.UI_THREAD_EXECUTOR); Task.callInBackground(new Callable<Boolean>() { @Override public Boolean c

  • Andorid 系统实现多种开机动画和logo切换功能

    前言 基于mtk6580,添加多logo和开关机动画切换 描述 目前android开机画面由三个部分(阶段)组成,第一部分在bootloader启动时显示(静态),第二部分在启动kernel时显示(静态),第三部分在系统启动时(bootanimation)显示(动画). 添加资源 1.在device/tangxun/tx6580_weg_m/ProjectConfig.mk,找到BOOT_LOGO=这项,记住这项内容(如hd720,),在vendor/mediatek/proprietary/b

  • Andorid TextView字幕效果实例

    一.效果图 二.代码 复制代码 代码如下: public class TextSubView extends TextView { private TextPaint mPaint; public TextSubView(Context context, AttributeSet attrs) { super(context, attrs); mPaint = new TextPaint(getPaint()); mPaint.setStyle(TextPaint.Style.STROKE);

  • Andorid实现精确到天时分秒的抢购倒计时

    今天项目用到了抢购时倒计时的功能 ,今天找了好多哥们,也百度了好多,但是没有自己喜欢并且能消化的.好不容易找到了一个能容易看懂的,然而又不符合我想要的需求,所以自己搞一下.不知道是否简单,但是最起码是项目的功能可以实现.(一下午,没白费.开心) 直接上代码好了,我相信都能看懂.我除外.(我搞了一下午)哎.反正现在懂点了... package com.qust.widght; import java.text.SimpleDateFormat; import java.util.Date; imp

  • Andorid自定义attr的各种坑

    在开发Andorid应用程序中,经常会自定义View来实现各种各样炫酷的效果,在实现这吊炸天效果的同时,我们往往会定义很多attr属性,这样就可以在XML中配置我们想要的属性值,以下就是定义属性值可能遇到的各种坑. 大家都知道怎么定义attr属性,一般如下: <declare-styleable name="Sample"> <attr name="custom" format="string|reference" />

  • Andorid开发之Picasso通过URL获取用户头像的圆形显示

    1.设置布局属性: <ImageView android:scaleType="fitXY"/> 2.BitmapUtils类-- 得到指定圆形的Bitmap对象 public static Bitmap circleBitmap(Bitmap source) { //获取Bitmap的宽度 int width = source.getWidth(); //以Bitmap的宽度值作为新的bitmap的宽高值. Bitmap bitmap = Bitmap.createBit

  • Andorid 状态管理之Lifecycle浅析

    目录 原理概述 构成 模型 源码 1. addObserver(observer) 2. sync() 3. setCurrentState.moveToState 监听 其他 1. Application.ActivityLifecycleCallbacks 总结 原理概述 Lifecycle主要用于Activity.Fragment这一类具有状态的组件的状态监听,最主要的一个作用就是将原先Activity.Fragment中的大量的生命周期相关的回调函数移出View层文件,从设计角度上来说,

  • Spring事务管理的使用细则浅析

    目录 Spring 事务管理接口 1.事务管理器接口 PlatformTransactionManager 2.事务定义接口 TransactionDefinition Spring 事务管理的实现方法 1.没有事务管理的情况分析 2.通过配置 XML 实现事务管理 3.利用注解实现事务管理 4.在业务层实现事务管理   事务(Transaction)是访问数据库的一个操作序列,这些操作要么都做,要么都不做,是一个不可分割的工作单元.通过事务,数据库能将逻辑相关的一组操作绑定在一起,以便保持数据

  • JSP状态管理的简单介绍

    JSP状态管理的简单介绍 一 http协议的无状态性 无状态性是指:当浏览器发送请求给服务器时,服务器响应客户端请求. 但是当同一个浏览器再次发送请求给服务器的时候,服务器并不知道它就是刚才那个浏览器. 简单地说,就是服务器不会去记得你,所以就是无状态协议. 二 保存用户状态的两大机制 Session Cookie 三 Cookie概述 Cookie:中文名称为"小甜饼",是Web服务器保存在客户端的一系列文本信息. 典型应用一:判断注册用户是否已经登录网站. 典型应用二:"

  • 浅谈Vuex的状态管理(全家桶)

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试.状态快照导入导出等高级调试功能. 以上是vuex的官方文档对vuex的介绍,官方文档对vuex的用法进行了详细的说明.这里就不再细讲vuex的各个用法,写这篇博客的目的只是帮助部分同学更快地理解并上手vuex.

  • Vue的Flux框架之Vuex状态管理器

    学习vue之前,最重要是弄懂两个概念,一是"what",要理解vuex是什么:二是"why",要清楚为什么要用vuex. Vuex是什么? Vuex 类似 React 里面的 Redux 的状态管理器,用来管理Vue的所有组件状态. 为什么使用Vuex? 当你打算开发大型单页应用(SPA),会出现多个视图组件依赖同一个状态,来自不同视图的行为需要变更同一个状态. 遇到以上情况时候,你就应该考虑使用Vuex了,它能把组件的共享状态抽取出来,当做一个全局单例模式进行管理

  • 详解vue组件化开发-vuex状态管理库

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试.状态快照导入导出等高级调试功能. 以上是vuex的官方文档对vuex的介绍,官方文档对vuex的用法进行了详细的说明.这里就不再细讲vuex的各个用法,写这篇博客的目的只是帮助部分同学更快地理解并上手vuex.

  • 一篇看懂vuejs的状态管理神器 vuex状态管理模式

    关于vuex类的新闻最近很多,看到眼热就去查了下资料,然后扯出来一堆flux.redux.state.state之类的概念,以及大型工程必要性之类的.看官方手册也是昏昏然. 然而,我还是弄懂了!我准备从demo出发,以同样的一个最简单的demo,演示两种情况下的代码编写情况: 单纯依赖于vue.js 依赖vue.js,也使用了vuex技术 目的是通过对比引出vuex的概念.优势和劣势.也许这是目前最接地气的vuex的介绍吧:).所以无论如何在了解vuex之前,你必须懂得vue.js(好像废话:)

  • ASP.NET2.0服务器控件之自定义状态管理

    在前面的系列文章中,我们曾经介绍了视图状态和控件状态的基本概念和典型应用,从中可以发现,视图状态和控件状态对于自定义服务器控件实现的重要性.本文将继续这一主题,重点介绍实现视图状态和控件状态自定义管理的方法. 自定义视图状态管理 在介绍视图状态时,我们曾经提到过:对于简单属性,例如,String.Int等类型,.NET执行引擎将自动启用默认视图状态管理机制,以便完成相应的功能.然而,如果开发人员在ViewState中保存的是自定义数据类型,或者需要实现自定义方式优化视图状态管理时,则必须实现自定

  • Vuex模块化实现待办事项的状态管理

    前言 在vue里,组件之间的作用域是独立的,父组件跟子组件之间的通讯可以通过prop属性来传参,但是在兄弟组件之间通讯就比较麻烦了.比如A组件要告诉一件事给B组件,那么A就要先告诉他们的爸组件,然后爸组件再告诉B.当组件比较多,要互相通讯的事情很多的话,爸组件要管他们那么多事,很累的.vuex正是为了解决这个问题,让多个子组件之间可以方便的通讯. 项目介绍 待办事项中的一个事件,它可能拥有几个状态,未完成.已完成.已取消或被删除等.这个事件需要在这多种状态之间切换,那么使用vuex来管理也是非常

  • 详解Vue中状态管理Vuex

    vuex是一个专门为vue.js设计的状态管理模式,并且也可以使用devtools进行调试. 在vuex出现之前,vue里面的状态是属于'单向数据流'.举个官网的例子: new Vue({ // state data () { return { count: 0 } }, // view template: `<div>{{ count }} </div`, // actions methods: { increment () { this.count++ } } }) 其中 state

随机推荐