安卓項目實戰之BaseActivity的封裝(已更新)

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() {

    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章