BaseFragment的封裝見博文:具有懶加載功能的 Fragment基類封裝和一般的Fragment基類封裝
BaseActivity封裝如下:
public abstract class BaseActivity extends AppCompatActivity {
private WeakReference<Activity> weakReference = null;
private boolean isFullScreen; // 設置是否去掉狀態欄,全屏顯示
private LoadingDialog dialog; // 子類共享的進度提示dialog
public void setFullScreen(boolean fullScreen) {
isFullScreen = fullScreen;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 設置要不要顯示狀態欄
setStatusShow();
// 設置是否全屏(去掉狀態欄和標題欄)
if (isFullScreen) {
setIsFullScreen();
}
//設置BaseActivity的佈局
setContentView(setLayout());
//綁定ButterKnife
ButterKnife.bind(this);
// 註冊,
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().register(this);
}
//將activity添加到管理列表中
if (weakReference == null) {
weakReference = new WeakReference<Activity>(this);
}
ActivityManager.getInstance().addActivity(weakReference.get());
// 設置所有activity的狀態欄顏色,推薦2個常用的第三方庫:StatusBarUtil
// https://github.com/laobie/StatusBarUtil
// https://github.com/gyf-dev/ImmersionBar
StatusBarUtil.setStatusBarColor(this, getResources().getColor(R.color.colorAccent));
// 初始化頁面
initView();
// 子類中需要獲取Activity異常銷燬時的值的時候使用
initState(savedInstanceState);
// 設置數據
initData();
// 設置監聽
setListener();
}
protected void setStatusShow() {
}
protected void setListener() {
}
protected void initData() {
}
// 當頁面因爲異常銷燬需要保存數據時調用該方法
protected void initState(Bundle savedInstanceState) {
}
protected abstract int setLayout();
protected void initView() {
}
/**
* EventBus默認綁定一個事件,防止源碼裏面去找方法的時候找不到報錯。
*
* @param activity
*/
@Subscribe
public void onEvent(BaseActivity activity) { }
@Override
protected void onDestroy() {
super.onDestroy();
// 取消註冊
EventBus.getDefault().unregister(this);
//將activity從列表中移除
ActivityManager.getInstance().removeActivity(weakReference.get());
// 處理華爲手機mlastsrvview內存泄露問題
FixMemLeakUtils.fixLeak(MyApplicationLike.getInstance());
}
/**
* 窗口全屏
*/
private void setIsFullScreen() {
this.getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
}
/**
* 進度彈框提示
*/
private void showDialogInfo(String info) {
if(dialog == null){
dialog = LoadingDialog.getInstance(info);
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
}else{
dialog.setTitle(info);
}
dialog.show();
}
/**
* 重寫getResources()方法,讓APP的字體不受系統設置字體大小影響
*/
@Override
public Resources getResources() {
Resources res = super.getResources();
Configuration config = new Configuration();
config.setToDefaults();
res.updateConfiguration(config, res.getDisplayMetrics());
return res;
}
}
上面的BaseActivity封裝只是作爲一個簡單的參考,您還可以添加更多的東西,比如控制跳轉的方法,設置屏幕是否旋轉等等的代碼邏輯。
關於上面 initState(savedInstanceState); 方法的使用,主要是用來處理當因爲特殊原因(比如系統內存不足時)導致activity重建時保存一些數據,具體細節可參見我的另一篇博文:安卓項目實戰之:Activity和Fragment重新創建時狀態的保存和恢復
Activity的棧管理類ActivityManager:
public class ActivityManager {
private List<Activity> activityList = new ArrayList<>();
private ActivityManager() {
}
public static ActivityManager getInstance() {
return ActivityManagerHolder.Instantce;
}
/**
* 靜態內部類獲取單例
*/
static class ActivityManagerHolder {
public static ActivityManager Instantce = new ActivityManager();
}
/**
* 添加activity
* @param activity
*/
public void addActivity(Activity activity){
if (!activityList.contains(activity)) {
activityList.add(activity);
}
}
/**
* 移除activity
* @param activity
*/
public void removeActivity(Activity activity){
if (activityList.contains(activity)) {
activityList.remove(activity);
}
}
/**
* 關閉所有的activity,退出應用
*/
public void finishActivitys(){
if (activityList != null && !activityList.isEmpty()) {
for (Activity activity1 : activityList) {
activity1.finish();
}
activityList.clear();
}
}
}
如果想在其他頁面銷燬Activity,可以調用如下代碼:
MyActivity.getInstance().finish();
處理華爲手機mlastsrvview內存泄露的FixMemLeakUtils工具類:
public class FixMemLeakUtils {
private static Field field;
private static boolean hasField = true;
public static void fixLeak(Context context) {
if (!hasField) {
return;
}
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm == null) {
return;
}
String[] arr = new String[]{"mLastSrvView"};
for (String param : arr) {
try {
if (field == null) {
try {
field = imm.getClass().getDeclaredField(param);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
if (field == null) {
hasField = false;
}
if (field != null) {
field.setAccessible(true);
field.set(imm, null);
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
Dialog加載中提示:
自定義對話框的實現使用了:對話框庫FlycoDialog-Master,具體使用參見博客:安卓項目實戰之強大的Dialog對話框庫FlycoDialog-Master
public class LoadingDialog extends BaseDialog<LoadingDialog> {
private static LoadingDialog loadingDialog = null;
private final String info;
private TextView tvInfo;
private LoadingDialog(Context context,String info) {
super(context);
this.info = info;
}
// 單例設計
public static LoadingDialog getInstance(String str) {
if (loadingDialog == null) {
loadingDialog = new LoadingDialog(MyApplicationLike.getInstance(),str);
}
return loadingDialog;
}
@Override
public View onCreateView() {
widthScale(0.35f);
// dimEnabled(false); // 去掉背景遮罩層
View inflate = View.inflate(mContext, R.layout.loading_dialog, null);
tvInfo = inflate.findViewById(R.id.tvInfo);
tvInfo.setText(info);
inflate.setBackgroundDrawable(
CornerUtils.cornerDrawable(Color.parseColor("#ffffff"), dp2px(5)));
return inflate;
}
public void setTitle(String str){
tvInfo.setText(str);
}
@Override
public void setUiBeforShow() {
}
}