1,網絡監聽 並及時通知觀察者 優勢,一個廣播接收者,可以搞定整個應用中需要監聽網絡的地方。集中處理一件事
註冊 一個 廣播接收者,用來監聽網絡的變化,並做爲被觀察者當前 網絡的狀態
當 activity 或 其他組件需要 監聽網絡變化時,註冊觀察者,當 不需要時,取消註冊
2,snackbar 代替 toast ,彈出方式更先進,可以接收點擊事件,可操作更多。 需要判斷虛擬鍵擋住 snackbar 的 問題
3,Activity 工具類,在oncreate中加入 工具類中,ondestory時 從 工具類中刪除 activity, 便於管理activity ,便於 銷燬指定的activity ,退出程序時銷燬所有的activity.
4,Application 中,exitApp()方法,當兩次點擊需要退出程序時調用:主要api : android.os.Process.killProcess(android.os.Process.myPid()); 及System.exit(0)
5,MVP模式:該項目中 activity 或 fragment 作爲 實現view 接口 , presenter 相當於個裝飾者,將 view 和 model聯繫人一塊。 在activity 或 fragment中,或取 persenter 對象,並渲染 view 。 注:從activity中的代碼中看,個人感覺優化不是特別明顯,是否應該會有更好的方式呢?
6,baseActivity:項目中,基類 activity 中,把生命週期中的方法,儘可能的用抽象方法實現,然後子類去實現抽象方法,這樣,子類儘可能的屏蔽了生命週期相關的處理。感覺這種處理方式很好,特別是涉及到共性的修改時,可以在基類中統一處理
7,Fragment 在 baseFragment中,同 baseActivity中一樣,用抽象方法去實現 然後子類實現抽象方法。
public abstract class BaseLazyFragment extends Fragment {
/**
* Log tag
*/
protected static String TAG_LOG = null;
/**
* Screen information
*/
protected int mScreenWidth = 0;
protected int mScreenHeight = 0;
protected float mScreenDensity = 0.0f;
/**
* context
*/
protected Context mContext = null;
private boolean isFirstResume = true;
private boolean isFirstVisible = true;
private boolean isFirstInvisible = true;
private boolean isPrepared;
private VaryViewHelperController mVaryViewHelperController = null;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mContext = activity;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO something like EventBus register
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (getContentViewLayoutID() != 0) {
return inflater.inflate(getContentViewLayoutID(), null);
} else {
return super.onCreateView(inflater, container, savedInstanceState);
}
// TODO return view
}
// TODO onViewCreated() after onCreateView
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// TODO findView,initView
ButterKnife.inject(this, view);
if (null != getLoadingTargetView()) {
mVaryViewHelperController = new VaryViewHelperController(getLoadingTargetView());
}
DisplayMetrics displayMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
mScreenDensity = displayMetrics.density;
mScreenHeight = displayMetrics.heightPixels;
mScreenWidth = displayMetrics.widthPixels;
initViewsAndEvents();
}
@Override
public void onDestroyView() {
super.onDestroyView();
ButterKnife.reset(this);
}
@Override
public void onDestroy() {
super.onDestroy();
if (isBindEventBusHere()) {
EventBus.getDefault().unregister(this);
}
}
@Override
public void onDetach() {
super.onDetach();
// for bug ---> java.lang.IllegalStateException: Activity has been destroyed
try {
Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
// after onViewCreated()
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// TODO IDentify this fragment first visible
initPrepare();
}
@Override
public void onResume() {
super.onResume();
if (isFirstResume) {
isFirstResume = false;
return;
}
if (getUserVisibleHint()) {
onUserVisible();
}
}
@Override
public void onPause() {
super.onPause();
if (getUserVisibleHint()) {
onUserInvisible();
}
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
if (isFirstVisible) {
isFirstVisible = false;
initPrepare();
} else {
onUserVisible();
}
} else {
if (isFirstInvisible) {
isFirstInvisible = false;
onFirstUserInvisible();
} else {
onUserInvisible();
}
}
}
private synchronized void initPrepare() {
if (isPrepared) {
onFirstUserVisible();
} else {
isPrepared = true;
}
}
/**
* when fragment is visible for the first time, here we can do some initialized work or refresh data only once
*/
protected abstract void onFirstUserVisible();
/**
* this method like the fragment's lifecycle method onResume()
*/
protected abstract void onUserVisible();
/**
* when fragment is invisible for the first time
*/
private void onFirstUserInvisible() {
// here we do not recommend do something
}
/**
* this method like the fragment's lifecycle method onPause()
*/
protected abstract void onUserInvisible();
/**
* get loading target view
*/
protected abstract View getLoadingTargetView();
/**
* init all views and add events
*/
protected abstract void initViewsAndEvents();
/**
* bind layout resource file
*
* @return id of layout resource
*/
protected abstract int getContentViewLayoutID();
}