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
<?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"); } }