继承Application管理生命周期

继承Application实现Android数据共享

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

 

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

 

这个接口有什么用呢?

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

这个时候我们就会想到一个需求实现,关闭所有 Activity !你还在通过继承 BaseActivity 在 BaseActivity 的 onCreate 中将这个 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 是公用的,当一个 Activity 在 onCreate 方法产生了一个对象 ,我们需要在这个 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  阅读(809)  评论(0)    收藏  举报