android 控件绑定生命周期

原创
02/18 20:20
阅读数 217

Android 绑定生命周期有很多好处,就不多说了。

AndroidX大法把绑定生命周期的思路做的非常的好,我找了网上公开的资料,都没有控件绑定生命周期这方面的文章。

Android的控件如何自动绑定生命周期?并且还要它能够在布局文件里面方便灵活的使用。

最简单的方法是,Activity使用androidx.appcompat.app.AppCompatActivity,它本身已经实现了LifecycleOwner接口,当然你也可以自己写一个。

import android.app.Activity;
import android.os.Bundle;
import android.os.PersistableBundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;

public abstract class BaseActivity extends Activity implements LifecycleOwner {
    private LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return lifecycleRegistry;
    }
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
    }
    public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
        super.onCreate(savedInstanceState,persistentState);
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
    }
    @Override
    protected void onStart() {
        super.onStart();
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }
    @Override
    protected void onResume() {
        super.onResume();
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    }

    @Override
    protected void onPause() {
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
        super.onPause();
    }

    @Override
    protected void onStop() {
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
        super.onDestroy();
    }
}

然后实现自己的控件,例如

package cn.l.lifecycletest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.OnLifecycleEvent;

@SuppressLint("AppCompatCustomView")
public  class MyTextView<T extends Context & LifecycleOwner >  extends TextView {
    T  activity;
    public MyTextView(final T context) {
        this(context,null);
    }

    public MyTextView(final T context, AttributeSet attrs) {
        super(context,attrs);
        activity=context;
        Lifecycle lifecycle= context.getLifecycle();
        lifecycle.addObserver(new LifecycleObserver() {
            @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
            public void onResume(){
                Log.d(activity.getClass().getSimpleName()+"-TextView:","onResumed");
            }
            @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
            public void onPause(){
                Log.d(activity.getClass().getSimpleName()+"-TextView:","onPause");
            }
        });

    }
}

这里构造方法的context 传进来的一定是Activity的实例,不会是其他的,但是构造方法的参数T泛型约束必须是Context不能是Activity,否则在布局文件里面使用,会无法实例化该控件。接下来,LifecycleObserver里面随便你写,方法名随便你定义,但是必须在方法上面附上相应的事件注解,这里面就举了两个比较常用的生命周期事件。

可以在适当的时机添加观察者,lifecycle.addObserver(),也可以在适当的时机移除观察者 

activity.getLifecycle().removeObserver();

这样,你的控件就可以非常灵活观察到Activity的生命周期了。

使用

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Main3Activity">

    <cn.l.lifecycletest.MyTextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="MyTextView"
        tools:layout_editor_absoluteX="130dp"
        tools:layout_editor_absoluteY="161dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
package cn.l.lifecycletest;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

或者

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MyTextView<MainActivity> myTextView=new MyTextView<>(this);
        setContentView(myTextView);
    }
}

这个传进来的context保存下来,因为getContext都是莫名奇妙的为空的。

本来想用instanceof来判断传进来的context是不是implements LifecycleOwner,但是运行时的东西必须运行才知道结果,调用者一旦忽略就麻烦了,如果抛出异常,又会存在复杂的try catch问题。

好东西一起分享!

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部