自从开始参加了工作之后,貌似已经很长时间没有写博客了,其中最主要的原因还是因为前些阵子要赶项目经常加班疏忽了,还好现在正值春节期间,我就可以好好整理一下自己的知识体系了。
什么是Application
Application和Activity,Service一样是android框架的一个系统组件,当android程序启动时系统会创建一个 application对象,用来存储系统的一些信息。通常我们是不需要指定一个Application的,这时系统会自动帮我们创建,如果需要创建自己 的Application,也很简单创建一个类继承 Application并在manifest的application标签中进行注册(只需要给Application标签增加个name属性把自己的 Application的名字定入即可)。具体代码如下
public class MyApplication extends Application {
private static MyApplication instances;
private int appCount = 0;
private boolean showForceLogoutDialog = false;
private boolean updateLocalData = false;
private String message = "";
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
@Override
public void onCreate() {
super.onCreate();
instances = this;
Utils.init(getApplicationContext());
if (BuildConfig.DEBUG) {
/*测试配置*/
Logger.addLogAdapter(new AndroidLogAdapter());
} else {
/*发布配置*/
// Bugly.setUserId(getApplicationContext(),
// String.valueOf(SignInUtils.getUserBean(getApplicationContext()).getId()));
}
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(Activity activity) {
appCount++;
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
appCount--;
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
});
}
public static MyApplication getInstances() {
return instances;
}
public int getAppCount() {
return appCount;
}
public boolean isShowForceLogoutDialog() {
return showForceLogoutDialog;
}
public void setShowForceLogoutDialog(boolean showForceLogoutDialog) {
this.showForceLogoutDialog = showForceLogoutDialog;
}
public boolean isUpdateLocalData() {
return updateLocalData;
}
public void setUpdateLocalData(boolean updateLocalData) {
this.updateLocalData = updateLocalData;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
什么是BaseActivity
BaseActivity主要作用是要作为Activity的公共父类存在,将那些公有的第三方初始化的工作放在里面避免重复代码,范例代码如下所示:
public abstract class BaseActivity extends RxAppCompatActivity {
//设置兼容5.0以下使用矢量图
static {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
}
//声明全局加载dialog
public Dialog loadingDialog;
//默认不是最后一页
public boolean lastPage = false;
//默认为第一页
public int page = BaseContants.DEFAULT_FIRST_PAGE;
//EventBus接收信息并处理信息
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(ServerMsgEvent serverMsgEvent) {
//如果APP在前台运行,弹出toast
if (!AppUtils.isBackground(this)) {
ToastUtils.showShortToast(serverMsgEvent.getDesc());
}
//如果登录信息失效且本地登录信息还在,调用强制退出逻辑
if (serverMsgEvent.getResult() == HttpResult.SERVER_RESULT_CODE_TOKEN_INVALID) {
if (!TextUtils.isEmpty(SignInUtils.getTokenId(this))) {
SignInUtils.forceLogout(this, serverMsgEvent.getDesc());
}
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
preInit();
super.setContentView(getLayoutId());
ButterKnife.bind(this);
setStatusBar();
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//注册EventBus
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().register(this);
}
initStatusBar();
initToolbar();
initProgressDialog();
initView();
initData();
}
@Override
protected void onResume() {
super.onResume();
//从后台切换到前台时,检查是否显示强制登出对话框,适用于透传推送踢出登录场景
if (MyApplication.getInstances().isShowForceLogoutDialog()) {
MyApplication.getInstances().setShowForceLogoutDialog(false);
Bundle bundle = new Bundle();
bundle.putString(BaseContants.KEY_NOTIFICATION_MESSAGE, MyApplication.getInstances().getMessage());
skipToActivity(DialogActivity.class, bundle);
}
从后台切换到前台时,检查是否更新本地筛选数据,保证及时更新筛选数据
if (MyApplication.getInstances().isUpdateLocalData()) {
MyApplication.getInstances().setUpdateLocalData(false);
Map<String, Object> map = new HashMap<>();
map.put(BaseContants.PARAM_CHECK_UPDATE_TYPE, BaseContants.CHECK_UPDATE_TYPE_ANDROID);
addDisposable(RetrofitManager.getAPIService()
.findDataVersion(map)
.compose(RxUtil.<HttpResult<FindDataVersion>>applySchedulers())
.compose(this.<HttpResult<FindDataVersion>>bindToLifecycle())
.subscribeWith(new BaseSubscriber<FindDataVersion>() {
@Override
public void handlerSuccess(final FindDataVersion findDataVersion) {
new Thread(new Runnable() {
@Override
public void run() {
DataVersionUtils.updateLocalData(BaseActivity.this, findDataVersion);
}
}).start();
}
}));
checkUpdate();
}
}
@Override
protected void onStop() {
super.onStop();
if (!AppUtils.isForeground()) {
//切换到后台时,设置更新筛选数据开关为打开,重新打开APP时更新数据
MyApplication.getInstances().setUpdateLocalData(true);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
String key = getPackageName() + BaseContants.SYMBOL_DOT + getClass().getSimpleName();
RetrofitManager.remove(key);
if (EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().unregister(this);
}
}
// 获取布局资源
protected abstract int getLayoutId();
// 初始化界面
protected abstract void initView();
// 初始化数据
protected abstract void initData();
//检查更新状态
public void checkUpdate() {
}
//预初始化
public void preInit() {
//android版本大于4.4,设置沉浸式状态栏
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
//设置状态栏
protected void setStatusBar() {
StatusBarUtil.setColor(this, getResources().getColor(R.color.colorPrimary));
}
//初始化状态栏
private void initStatusBar() {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
ViewGroup decorViewGroup = (ViewGroup) window.getDecorView();
View statusBarView = new View(window.getContext());
int statusBarHeight = getStatusBarHeight(window.getContext());
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, statusBarHeight);
params.gravity = Gravity.TOP;
statusBarView.setLayoutParams(params);
statusBarView.setBackgroundColor(ContextCompat.getColor(this, R.color.colorPrimaryDark));
decorViewGroup.addView(statusBarView);
ViewGroup mContentView = (ViewGroup) window.findViewById(Window.ID_ANDROID_CONTENT);
View mChildView = mContentView.getChildAt(0);
if (mChildView != null) {
//注意不是设置 ContentView 的 FitsSystemWindows, 而是设置 ContentView 的第一个子 View . 预留出系统 View 的空间.
mChildView.setFitsSystemWindows(true);
}
}
//获取状态栏的高度
private static int getStatusBarHeight(Context context) {
int statusBarHeight = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
}
return statusBarHeight;
}
//初始化ToolBar
public void initToolbar() {
Toolbar toolbar = findViewById(R.id.toolbar);
if (toolbar != null) {
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
}
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
// 给左上角图标的左边加上一个返回的图标
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
}
//初始化化进度对话框
public void initProgressDialog() {
View v = LayoutInflater.from(this).inflate(R.layout.loading_progress, null);
RelativeLayout layout = v.findViewById(R.id.dialog_loading_view);
loadingDialog = new Dialog(this, R.style.LoadingDialogStyle);
loadingDialog.setCancelable(true);
loadingDialog.setCanceledOnTouchOutside(false);
loadingDialog.setContentView(layout, new RelativeLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
Window window = loadingDialog.getWindow();
if (window != null) {
WindowManager.LayoutParams lp = window.getAttributes();
lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
window.setGravity(Gravity.CENTER);
window.setAttributes(lp);
window.setWindowAnimations(R.style.PopWindowAnimStyle);
}
}
//被观察者与观察者之间添加订阅关系
protected void addDisposable(Disposable disposable) {
String key = getPackageName() + BaseContants.SYMBOL_DOT + getClass().getSimpleName();
RetrofitManager.add(key, disposable);
}
//跳转到任意界面,并且通过bundle携带数据
protected void skipToActivity(Class<?> clazz, Bundle bundle) {
Intent intent = new Intent(this, clazz);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivity(intent);
}
//跳转到任意界面结束当前界面,并且通过bundle携带数据
protected void skipToActivityAndFinish(Class<?> clazz, Bundle bundle) {
Intent intent = new Intent(this, clazz);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivity(intent);
finish();
}
//跳转到任意界面,通过bundle传递数据,并且通过request返回数据给当前界面
protected void skipToActivityForResult(Class<?> clazz, Bundle bundle, int requestCode) {
Intent intent = new Intent(this, clazz);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivityForResult(intent, requestCode);
}
//关闭当前界面
protected void closeActivity(Bundle bundle) {
if (bundle != null) {
Intent intent = new Intent();
intent.putExtras(bundle);
setResult(RESULT_OK, intent);
}
finish();
}
}
什么是BaseFragment
BaseFragment的作用大体是和BaseActivity一致,也是作为Fragment的公共父类存在,在其中主要是对Fragment进行初始化以及对fragment进行懒加载,范例代码如下所示
public abstract class BaseFragment extends RxFragment {
Unbinder unbinder;
//声明一个view
protected View rootView;
//记录位置标签
String mPositionTag = "";
//记录开启进度条的情况,只能开一个
private int count;
//当前Fragment是否处于可见状态标志,防止因ViewPager的缓存机制而导致回调函数的触发
private boolean isFragmentVisible;
//是否是第一次开启网络加载
public boolean isFirst;
//刷新默认为第一页
public int page = BaseContants.DEFAULT_FIRST_PAGE;
//默认不是最后一页
public boolean lastPage = false;
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(SignOrBindEvent signOrBindEvent) {
initData();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if(rootView!=null) {
rootView= inflater.inflate(getLayoutId(), container, false);
}
unbinder = ButterKnife.bind(this, rootView);
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().register(this);
}
initView();
initData();
if(isFragmentVisible&&!isFirst){
onFragmentVisibleChange(true);
}
return rootView;
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
if (EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().unregister(this);
}
String key = Utils.getContext().getApplicationContext().getPackageName() + BaseContants.SYMBOL_DOT + getClass().getSimpleName() + mPositionTag;
RetrofitManager.remove(key);
}
protected abstract int getLayoutId();
protected abstract void initView();
protected abstract void initData();
protected void addDisposable(Disposable disposable) {
String key = Utils.getContext().getPackageName() + BaseContants.SYMBOL_DOT + this.getClass().getSimpleName();
RetrofitManager.add(key, disposable);
}
protected void addDisposable(Disposable disposable, String positionTag) {
String key = "";
mPositionTag = positionTag;
key = Utils.getContext().getApplicationContext().getPackageName() + BaseContants.SYMBOL_DOT + getClass().getSimpleName() + positionTag;
RetrofitManager.add(key, disposable);
}
/**
* 跳转到指定的Activity
*/
protected void skipToActivity(Class<?> clazz, Bundle bundle) {
Intent intent = new Intent(getActivity(), clazz);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivity(intent);
}
/**
* 跳转到指定的Activity并结束当前Activity
*/
protected void skipToActivityAndFinish(Class<?> clazz, Bundle bundle) {
Intent intent = new Intent(getActivity(), clazz);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivity(intent);
if (getActivity() != null) {
getActivity().finish();
}
}
/**
* 带返回的跳转到指定Activity
*/
protected void skipToActivityForResult(Class<?> clazz, Bundle bundle, int requestCode) {
Intent intent = new Intent(getActivity(), clazz);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivityForResult(intent, requestCode);
}
/**
* 关闭Activity
*/
protected void closeActivity(Bundle bundle) {
Intent intent = new Intent();
if (bundle != null) {
intent.putExtras(bundle);
}
if (getActivity()!=null){
getActivity().setResult(Activity.RESULT_OK, intent);
getActivity().finish();
}
}
/**
* 设置Fragment是否可见
*/
@Override
public void setUserVisibleHint(boolean isVisibleToUser){
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
isFragmentVisible=true;
}
if(rootView==null){
return;
}
//可见,并且没有加载过
if(!isFirst&&isFragmentVisible){
onFragmentVisibleChange(true);
}
//由可见-->不可见 已经加载过
if(isFragmentVisible){
onFragmentVisibleChange(false);
isFragmentVisible = false;
}
}
/**
* 当前fragment可见状态发生变化时会回调该方法
* 如果当前Fragment的是第一次加载,等待onCreateView后才会回调该方法,其他情况回调时机跟{@link #setUserVisibleHint(boolean)一致
* 在该回调方法中你可以做一些加载数据的操作,甚至是控件的操作
* @param isVisible true 不可见 -> 可见 ,false 可见 -> 不可见
*/
protected void onFragmentVisibleChange(boolean isVisible){
}
}
总结
当然了,我在这里也只是做了一个示范,我相信一定会有更好的写法,欢迎志同道合的朋友提出宝贵意见,共同学习进步!