开源项目AndroidReview学习小结(1)

简介:

启动

很经典的使用handler+子线程的延时加载方式,多了一个权限检查,应该是6.0系统中权限限制后需要用户手动设置,主要使用到一些系统intent的使用如启动应用设置的如

    // 启动应用的设置
    private void startAppSettings() {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse(PACKAGE_URL_SCHEME + getPackageName()));
        startActivity(intent);
    }

需要在6.0系统做权限检查的可以去参考一下,顺便说一下,这里作者的处理方式是将相应的权限放置数组中检查权限,若是缺少通过startActivityForResult方式启动权限处理Actvity,处理完回调继续进行流程。

基类

稍微有点的经验的小伙伴写一个app时候都会先写上BaseActvity、BaseFragment,这里体现出很好的代码重用的思想。比如目前最常见的titlebar,每个Actvity都有,但是不同的Actvity的titlebar字段是不一样的,为了干掉冗余的代码可以都集成到基类中;Activity的入站管理等等,这些全局或者公共部分都可以放入一个基类 
来看下作者的BaseActvity部分代码

public abstract class BaseActivity extends AppCompatActivity {

    protected Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        onBeforeSetContentLayout();
        //禁止横屏省去在配置文件中逐个设置
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        //base类中都会有App管理,将activity统一入栈,可以在退出时全局退出
        AppManager.getAppManager().addActivity(this);
//        隐藏ToolBar
//        hideToolBar();
        Logger.d("当前Activity 栈中有:" + AppManager.getAppManager().getActivityCount() + "个Activity");
}


    /**
     * 隐藏ToolBar
     */
    public void hideToolBar() {
        if (getSupportActionBar() != null) {
            getSupportActionBar().hide();
        }
    }
……
……
}

作者在基类中封装了titleBar、Actvity的入栈管理、禁止横屏。

  • titlebar 
    这个就不多说了

  • Activty全局管理, 
    一般都是用一个工具类来分装AppManager.getAppManager().addActivity(this); 将每个启动的Actvity加入到一个队列中管理,便于两次back全局退出或者按安全退出按钮。这个工具类后面会有分析

  • 禁止横屏 
    通常都是这样的,横屏之后actvity都会销毁重建处理起来不方面,直接禁止横屏得了,还有一种方式就是在配置文件中对需要禁止横屏的单独配置,这里通过代码全局禁止了横屏。

其他的部分一看作者就是从以前的项目中copy来的,那个TDevice关闭软键盘、状态栏兼容性,其实还可以在BaseAcivty中假如一些字体设置、actvity完结后的换场动画,actvity的透明度等等

再来看看作者的BaseFragment部分代码 
只完成一件事,懒加载 重写了fragment中的setUserVisibleHint

public abstract class BaseFragment extends Fragment {

    /**
     * Fragment当前状态是否可见
     */
    protected boolean isVisible;
    protected boolean isCreate = true;

    protected BaseActivity mActivity;

    @Override
    public void onAttach(Activity activity) {
        this.mActivity = (BaseActivity) activity;
        super.onAttach(activity);

    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }


    /**
     * 实现该方法即可实现可见再加载。不可见不加载的效果!!!
     *
     * @param isVisibleToUser
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        isCreate = false;
        if (getUserVisibleHint()) {
            isVisible = true;
            onVisible();
        } else {
            isVisible = false;
            onInvisible();
        }
    }
    ……
    ……

在继承的fragment中的onccreateView中还会配合使用缓存来判断是否需要再次加载

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        if (mRootView == null) {
            mRootView = getRootView();

            initArguments();//初始化参数

            creatBaseViews();

            createViewsOrListener();

        }
        //缓存的mRootView需要判断是否已经被加过parent, 如果有parent需要从parent删除,要不然会发生这个mRootView已经有parent的错误。
        ViewGroup parent = (ViewGroup) mRootView.getParent();
        if (parent != null) {
            parent.removeView(mRootView);
        }
        return mRootView;


    }

这里多说一句,其实还有一种防止fragment每次重新加载方式,就是使用viewpager+fragment方式,在viewpager中pager.setOffscreenPageLimit(2);这里表示每次缓存俩个fragmengt,作者这里采用 FragmentTabHost方式搭建底部tab,只能对每个fragment进行处理

框架

这里作者采用的是 FragmentTabHost搭建的方式,个人比较不喜欢这种方式,首先,需要手动消除Tab切换时候按钮之间的分割线,而且不能够滑动切换比较僵硬,推荐radiobutton+viewpager+fragment,可以看看我早期写的一个demo简单app框架,不过作者使用枚举类处理fragment的方式让我眼前一亮,原谅我的少见多怪吧。 
Indicator.actvity

public enum Indicator {

    REVIEW(0, R.string.main_tab_name_review, R.drawable.tab_icon_review,
            ReviewFragment.class),

    TEST(1, R.string.main_tab_name_test, R.drawable.tab_icon_test,
            TestFragment.class),

    SETTING(2, R.string.main_tab_name_setting, R.drawable.tab_icon_other,
            SettingFragment.class);


    private int idx;
    private int resName;
    private int resIcon;
    private Class<?> clz;

    private Indicator(int idx, int resName, int resIcon, Class<?> clz) {
        this.idx = idx;
        this.resName = resName;
        this.resIcon = resIcon;
        this.clz = clz;
    }

    public int getIdx() {
        return idx;
    }

    public void setIdx(int idx) {
        this.idx = idx;
    }

    public int getResName() {
        return resName;
    }

    public void setResName(int resName) {
        this.resName = resName;
    }

    public int getResIcon() {
        return resIcon;
    }

    public void setResIcon(int resIcon) {
        this.resIcon = resIcon;
    }

    public Class<?> getClz() {
        return clz;
    }

    public void setClz(Class<?> clz) {
        this.clz = clz;
    }
}

在MainActivity中通过Indicator[] indicators = Indicator.values();就将枚举放到数组中了,这里values()方法是编译器添加的静态方法,Enum类中并没有该方法,该方法可以遍历枚举的实例。

再按一次退出应用

大家在使用App时经常会看到这个toast,这个项目中也可以学到,主要是在MainActivity中重写onKeyDown方法,再加上俩个工具类,DoubleClickExitHelper,AppManager(堆栈式管理Actvity) 
MainActivity中重写onKeyDown方法

  @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {

            return mDoubleClickExit.onKeyDown(keyCode, event);
        }
        return super.onKeyDown(keyCode, event);
    }

如果你的app是侧滑式的需要判断一下抽屉是否打开,要是抽屉打开就关闭抽屉而不是退出

 @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if(mDrawerLayout.isDrawerOpen(GravityCompat.START)){
                mDrawerLayout.closeDrawers();
                return true;
            }

            return DoubleClickExit.onKeyDown(keyCode, event);
        }
        return super.onKeyDown(keyCode, event);

    }

DoubleClickExitHelper工具类主要是使用handler方式获取到主线程的消息队列new Handler(Looper.getMainLooper());然后再onKyDown方法中延时处理,选择再按一次也许是防止用户点击出错吧。

关于网络

这里采用的bmob的云后台来管理数据,bmob提供一个云的数据库来存储我们的数据,传送门 已经弄了一个demo来玩了,挺不错的。下篇再继续介绍各个tab中的比较好的技术点。

转载:http://blog.csdn.net/xsf50717/article/details/51005571

目录
相关文章
|
设计模式 Java Android开发
安卓应用开发中的内存泄漏检测与修复
【9月更文挑战第30天】在安卓应用开发过程中,内存泄漏是一个常见而又棘手的问题。它不仅会导致应用运行缓慢,还可能引发应用崩溃,严重影响用户体验。本文将深入探讨如何检测和修复内存泄漏,以提升应用性能和稳定性。我们将通过一个具体的代码示例,展示如何使用Android Studio的Memory Profiler工具来定位内存泄漏,并介绍几种常见的内存泄漏场景及其解决方案。无论你是初学者还是有经验的开发者,这篇文章都将为你提供实用的技巧和方法,帮助你打造更优质的安卓应用。
|
消息中间件 数据采集 存储
大数据数据采集的数据采集(收集/聚合)的Flume之数据采集流程的Channel的Kafka Channel
在大数据处理和管理中,数据采集是非常重要的一环。为了更加高效地进行数据采集,Flume作为一种流式数据采集工具得到了广泛的应用。其中,Flume的Channel模块是实现数据缓存和传输的核心模块之一。本文将介绍Flume中的Kafka Channel,讲解其数据采集流程。
347 0
|
5天前
|
云安全 人工智能 安全
AI被攻击怎么办?
阿里云提供 AI 全栈安全能力,其中对网络攻击的主动识别、智能阻断与快速响应构成其核心防线,依托原生安全防护为客户筑牢免疫屏障。
|
15天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
9天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
602 214
|
存储 人工智能 监控
从代码生成到自主决策:打造一个Coding驱动的“自我编程”Agent
本文介绍了一种基于LLM的“自我编程”Agent系统,通过代码驱动实现复杂逻辑。该Agent以Python为执行引擎,结合Py4j实现Java与Python交互,支持多工具调用、记忆分层与上下文工程,具备感知、认知、表达、自我评估等能力模块,目标是打造可进化的“1.5线”智能助手。
838 61
|
7天前
|
人工智能 移动开发 自然语言处理
2025最新HTML静态网页制作工具推荐:10款免费在线生成器小白也能5分钟上手
晓猛团队精选2025年10款真正免费、无需编程的在线HTML建站工具,涵盖AI生成、拖拽编辑、设计稿转代码等多种类型,均支持浏览器直接使用、快速出图与文件导出,特别适合零基础用户快速搭建个人网站、落地页或企业官网。
1238 157
|
4天前
|
编解码 Linux 数据安全/隐私保护
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
236 138