继承Application管理生命周期

继承Application实现Android数据共享

http://www.jianshu.com/p/75a5c24174b2

 

jessyan提出一个思路,用Application + 接口来管理扩展每个activity的生命周期

 

这个接口有什么用呢?

Application 提供有一个 registerActivityLifecycleCallbacks() 的方法,需要传入的参数就是这个 ActivityLifecycleCallbacks 接口,作用和你猜的没错,就是在你调用这个方法传入这个接口实现类后,系统会在每个 Activity 执行完对应的生命周期后都调用这个实现类中对应的方法,请记住是每个!

这个时候我们就会想到一个需求实现,关闭所有 Activity !你还在通过继承 BaseActivityBaseActivityonCreate 中将这个 Activity 加入集合???

那我现在就告诉你这样的弊端,如果你 App 中打开有其他三方库的 Activity ,这个三方库肯定不可能继承你的 BaseActivity ,这时你怎么办?怎么办?

这时 ActivityLifecycleCallbacks 就派上用场了, App 中的所有 Activity 只要执行完生命周期就一定会调用这个接口实现类的对应方法, 那你就可以在 onActivityCreated 中将所有 Activity 加入集合,这样不管你是不是三方库的 Activity 我都可以遍历集合 finish 所有的 Activity

 

现在就按照他给的思路实现toolbar

 
首先定义toolbar的xml,我用了v7的toolbar
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:layout_gravity="top"
    android:background="?attr/colorPrimary"/>

使用toolbar

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

    <include layout = "@layout/app_toolbar"/>

</LinearLayout>

继承application,重写接口

public class LApplication extends Application {


    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                if (activity.findViewById(R.id.toolbar) != null) {
                    if (activity instanceof AppCompatActivity) {
                        Toolbar toolbar = (Toolbar) activity.findViewById(R.id.toolbar);
                        ((AppCompatActivity) activity).setSupportActionBar(toolbar);
                        ((AppCompatActivity) activity).getSupportActionBar().setDisplayShowTitleEnabled(false);
                        toolbar.setTitle(activity.getTitle().toString());
                    }
                }
            }
    }
}

这样在activity的super.oncreate时就会调用application的这段代码

public class MainActivity extends AppCompatActivity {

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

所以这里要注意先setContentView再调用super.onCreate

最后设置application

<application android:name=".LApplication"

完成效果:

 

 还可以同一管理activity,比如加上ButterKnife注解

把butterKnife放到application里统一管理

public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                ButterKnife.bind(activity);
}

Activity就可以直接使用实例了

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.am_tv)
    TextView tv;

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

        tv.setText("666");
    }
}

 

但是又有一个问题出现这个 ActivityLifecycleCallbacks 是公用的,当一个 ActivityonCreate 方法产生了一个对象 ,我们需要在这个 Activity 执行 onDestroy 时用到这个对象,怎么办?因为每个 Activity 都要产生这个对象,我们不可能把这个对象存储在 ActivityLifecycleCallbacks 中啊

现在就可以用到 Activity.getIntent 来存储一些数据, Intent 中持有一个 Bundle 对象可以存储一些数据,

public class WEApplication extends BaseApplication{

    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                ActivityBean bean = new ActivityBean();
                Unbinder unbinder = ButterKnife.bind(activity);
                bean.setUnbinder(unbinder);
                activity.getIntent().putExtra("ActivityBean", bean);
           }

            ...

            @Override
            public void onActivityDestroyed(Activity activity) {
                ActivityBean bean = activity.getIntent().getParcelableExtra("ActivityBean");
                bean.getUnbinder().unbind();
            }
        }

        });
    }
}

需要Activity初始化某些事,或者提供某些数据

BaseActivity 有些时候需要,子 Activity 实现某些方法,或者提供某些数据,如需要子 Activity
实现 initView 返回 setContentView() 中的布局 ID ,实现 initData 初始化一些数据,这样就可以不需要 Activity 再重写 onCreate ,达到规范的目的, 这样使用 ActivityLifecycleCallbacks 同样能做到,那我该怎么做呢?

只需要 Activity 实现某个自定义接口

public interface IActivity {

    int initView();

    void initData();

}

然后在 ActivityLifecycleCallbacks 的 onActivityCreated 中调用这些方法,就可以实现

public class LApplication extends Application{

    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            if (activity instanceof IActivity) {
               activity.setContentView(((IActivity)activity).initView());
               ((IActivity)activity).initData();          
            }

           }

            ...

        }

        });
    }
}

 

demo如下:

public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                if(activity instanceof IActivity)
                {
                    activity.setContentView(((IActivity) activity).initView());
                    ButterKnife.bind(activity);
                    ((IActivity) activity).initData();
                }
                else
                {
                    ButterKnife.bind(activity);
                }
                if (activity.findViewById(R.id.toolbar) != null) {
                    if (activity instanceof AppCompatActivity) {
                        Toolbar toolbar = (Toolbar) activity.findViewById(R.id.toolbar);
                        ((AppCompatActivity) activity).setSupportActionBar(toolbar);
                        ((AppCompatActivity) activity).getSupportActionBar().setDisplayShowTitleEnabled(false);
                        toolbar.setTitle(activity.getTitle().toString());
                    }
                }
            }

这样activity只用这样写就行了,oncreate都不用了

public class MainActivity extends AppCompatActivity implements IActivity{

    @BindView(R.id.am_tv)
    TextView tv;

    @Override
    public int initView() {
        return R.layout.activity_main;
    }

    @Override
    public void initData() {
        tv.setText("666");
    }
}

 

 

 
 
posted @ 2017-07-30 17:21  qlky  阅读(764)  评论(0编辑  收藏  举报