安卓项目实战之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() {

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