b2f7b35134336f59fa3f3fcf46617eeaa8cd470f.svn-base 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. package com.hjq.base;
  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.os.Bundle;
  6. import android.os.Handler;
  7. import android.os.Looper;
  8. import android.os.SystemClock;
  9. import android.support.annotation.Nullable;
  10. import android.support.v7.app.AppCompatActivity;
  11. import android.view.View;
  12. import android.view.inputmethod.InputMethodManager;
  13. import java.util.Random;
  14. /**
  15. * desc : Activity 基类
  16. */
  17. public abstract class BaseActivity extends AppCompatActivity {
  18. private static final Handler HANDLER = new Handler(Looper.getMainLooper());
  19. @Override
  20. protected void onCreate(Bundle savedInstanceState) {
  21. super.onCreate(savedInstanceState);
  22. initActivity();
  23. }
  24. protected void initActivity() {
  25. initLayout();
  26. initView();
  27. initData();
  28. }
  29. protected void initLayout() {
  30. if (getLayoutId() > 0) {
  31. setContentView(getLayoutId());
  32. }
  33. }
  34. // 引入布局
  35. protected abstract int getLayoutId();
  36. // 标题栏
  37. protected abstract int getTitleId();
  38. // 初始化控件
  39. protected abstract void initView();
  40. // 初始化数据
  41. protected abstract void initData();
  42. @Override
  43. public void finish() {
  44. hideSoftKeyboard();
  45. super.finish();
  46. }
  47. /**
  48. * 延迟执行
  49. */
  50. public final boolean post(Runnable r) {
  51. return postDelayed(r, 0);
  52. }
  53. /**
  54. * 延迟一段时间执行
  55. */
  56. public final boolean postDelayed(Runnable r, long delayMillis) {
  57. if (delayMillis < 0) {
  58. delayMillis = 0;
  59. }
  60. return postAtTime(r, SystemClock.uptimeMillis() + delayMillis);
  61. }
  62. /**
  63. * 在指定的时间执行
  64. */
  65. public final boolean postAtTime(Runnable r, long uptimeMillis) {
  66. return HANDLER.postAtTime(r, this, uptimeMillis);
  67. }
  68. @Override
  69. protected void onDestroy() {
  70. super.onDestroy();
  71. // 移除和这个 Activity 相关的消息回调
  72. HANDLER.removeCallbacksAndMessages(this);
  73. }
  74. /**
  75. * 如果当前的 Activity(singleTop 启动模式) 被复用时会回调
  76. */
  77. @Override
  78. protected void onNewIntent(Intent intent) {
  79. super.onNewIntent(intent);
  80. // 设置为当前的 Intent,避免 Activity 被杀死后重启 Intent 还是最原先的那个
  81. setIntent(intent);
  82. }
  83. /**
  84. * 获取当前 Activity 对象
  85. */
  86. @SuppressWarnings("unchecked")
  87. public <A extends BaseActivity> A getActivity() {
  88. return (A) this;
  89. }
  90. /**
  91. * 和 setContentView 对应的方法
  92. */
  93. public View getContentView() {
  94. return getWindow().getDecorView();
  95. }
  96. /**
  97. * startActivity 方法优化
  98. */
  99. public void startActivity(Class<? extends Activity> cls) {
  100. startActivity(new Intent(this, cls));
  101. }
  102. public void startActivityFinish(Class<? extends Activity> cls) {
  103. startActivityFinish(new Intent(this, cls));
  104. }
  105. public void startActivityFinish(Intent intent) {
  106. startActivity(intent);
  107. finish();
  108. }
  109. /**
  110. * setResult 方法优化
  111. */
  112. public void finishResult() {
  113. finishResult(RESULT_OK, null);
  114. }
  115. public void finishResult(int resultCode) {
  116. finishResult(resultCode, null);
  117. }
  118. public void finishResult(int resultCode, Intent data) {
  119. setResult(resultCode, data);
  120. finish();
  121. }
  122. /**
  123. * startActivityForResult 方法优化
  124. */
  125. private ActivityCallback mActivityCallback;
  126. private int mActivityRequestCode;
  127. public void startActivityForResult(Class<? extends Activity> cls, ActivityCallback callback) {
  128. startActivityForResult(new Intent(this, cls), null, callback);
  129. }
  130. public void startActivityForResult(Intent intent, ActivityCallback callback) {
  131. startActivityForResult(intent, null, callback);
  132. }
  133. public void startActivityForResult(Intent intent, @Nullable Bundle options, ActivityCallback callback) {
  134. if (mActivityCallback == null) {
  135. mActivityCallback = callback;
  136. // 随机生成请求码,这个请求码在 0 - 255 之间
  137. mActivityRequestCode = new Random().nextInt(255);
  138. startActivityForResult(intent, mActivityRequestCode, options);
  139. }else {
  140. // 回调还没有结束,所以不能再次调用此方法,这个方法只适合一对一回调,其他需求请使用原生的方法实现
  141. throw new IllegalArgumentException("Error, The callback is not over yet");
  142. }
  143. }
  144. @Override
  145. protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
  146. if (mActivityCallback != null && mActivityRequestCode == requestCode) {
  147. mActivityCallback.onActivityResult(resultCode, data);
  148. mActivityCallback = null;
  149. }else {
  150. super.onActivityResult(requestCode, resultCode, data);
  151. }
  152. }
  153. /**
  154. * 处理 Activity 多重跳转:https://www.jianshu.com/p/579f1f118161
  155. */
  156. @Override
  157. public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
  158. if (startActivitySelfCheck(intent)) {
  159. hideSoftKeyboard();
  160. // 查看源码得知 startActivity 最终也会调用 startActivityForResult
  161. super.startActivityForResult(intent, requestCode, options);
  162. }
  163. }
  164. private String mStartActivityTag;
  165. private long mStartActivityTime;
  166. /**
  167. * 检查当前 Activity 是否重复跳转了,不需要检查则重写此方法并返回 true 即可
  168. *
  169. * @param intent 用于跳转的 Intent 对象
  170. * @return 检查通过返回true, 检查不通过返回false
  171. */
  172. protected boolean startActivitySelfCheck(Intent intent) {
  173. // 默认检查通过
  174. boolean result = true;
  175. // 标记对象
  176. String tag;
  177. if (intent.getComponent() != null) { // 显式跳转
  178. tag = intent.getComponent().getClassName();
  179. }else if (intent.getAction() != null) { // 隐式跳转
  180. tag = intent.getAction();
  181. }else { // 其他方式
  182. return true;
  183. }
  184. if (tag.equals(mStartActivityTag) && mStartActivityTime >= SystemClock.uptimeMillis() - 500) {
  185. // 检查不通过
  186. result = false;
  187. }
  188. mStartActivityTag = tag;
  189. mStartActivityTime = SystemClock.uptimeMillis();
  190. return result;
  191. }
  192. /**
  193. * 隐藏软键盘
  194. */
  195. private void hideSoftKeyboard() {
  196. // 隐藏软键盘,避免软键盘引发的内存泄露
  197. View view = getCurrentFocus();
  198. if (view != null) {
  199. InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
  200. if (manager != null) manager.hideSoftInputFromWindow(view.getWindowToken(), 0);
  201. }
  202. }
  203. /**
  204. * Activity 回调接口
  205. */
  206. public interface ActivityCallback {
  207. /**
  208. * 结果回调
  209. *
  210. * @param resultCode 结果码
  211. * @param data 数据
  212. */
  213. void onActivityResult(int resultCode, @Nullable Intent data);
  214. }
  215. }