Android日常业务开发小tips总结

一、日常开发过程中的小Tips

001 同时发出多个接口请求,如何在所有接口都请求完成之后再刷新UI?

这种面试中常被问到的题,居然在实际编程中真的遇到了。

这是在什么场景下出现的呢?

在多type的RecyclerView的使用中,有这样一个场景:某一个item涉及到了三个接口请求。也就是说要请求三个接口,才能得到这个item的全部数据。编程之初,我就是请求三次,这样问题就出现了,这个item会在页面加载完成后闪三次。这极大的影响了用户体验。

于是我就提出了本文这个问题:同时发出多个接口请求,如何在所有接口都请求完成之后再刷新UI?

经过一番思索,我想出了两个办法:

(1)一共有三个接口,那就在第一个接口请求成功之后,去请求下一个接口

(2)定义一个全局变量,在要发出接口请求时,置为0;然后发出一个接口请求,值加1,并判断该值是否为3;如果为3,刷新UI.

两种方案对比一下,最终选择了第二种。

002 如何避免用户快速点击按钮?

public class CheckDoubleClick {

    private static long lastClickTime = 0;

    public static boolean isFastDoubleClick() {
        long time = System.currentTimeMillis();
        long timeD = time - lastClickTime;
        if (0 < timeD && timeD < 500) {
            return true;
        }
        lastClickTime = time;
        return false;
    }
}

以上代码非常简单易用

003 遍历删除list元素

Iterator<ScheduleDate> iterator = scheduleDateList.iterator();
        while (iterator.hasNext()) {
            ScheduleDate date = iterator.next();
            if (date == null || !TextUtils.isEmpty(date.getFestival())) {
                iterator.remove();
            }
        }

如果要是采用for循环,有可能会出现某些元素删除不掉的坑。

因为list每remove掉一个元素后,后面的元素会向前移动,此时如果执行i+1,则刚刚被移过来的元素没有被读取

要解决这个问题,除了用iterator,也可以从后向前遍历。

004 请求权限代码(已唤起通讯录权限为例)

//相关权限申请
    private void requestPermission() {
        if (Build.VERSION.SDK_INT >= 23) {
            final List<String> permissionsList = new ArrayList<>();
            addPermission(permissionsList, Manifest.permission.READ_CONTACTS);
            if (permissionsList.size() > 0) {
                requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), CONTACTS_PERMISSION_REQUEST_CODE);
            } else {
                openContacts();
            }
        }
    }
private void openContacts() {
        startActivityForResult(new Intent(Intent.ACTION_PICK,
                ContactsContract.Contacts.CONTENT_URI), CONTACTS_REQUEST_CODE);
    }
private boolean addPermission(List<String> permissionsList, String permission) {
        if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
            permissionsList.add(permission);
            return false;
        }
        return true;
    }

005 使用getApplicationContext还是getContext?

当一个单例对象需要持有context,应该使用getApplicationContext,否则会引起内存泄漏。所以原则上,我们应该尽量用getApplicationContext!那么,有没有什么场景下不要用getApplicationContext呢?在启动activity时,最好不要使用,因为applicationContext是没有任务栈的。

006 targetSdkVersion、compileSdkVersion、buildToolVersion理解

1、targetSdkVersion:表示最高能使用的api新特性。比如targetSdkVersion是19,那即使使用了api 23的新特性,实际运行时,也不会使用该特性。

2、compileSdkVersion:告诉gradle使用哪个版本的sdk编译应用。

3、buildToolVersion:构建工具的版本。构建工具包括:aapt、dx等。

007 若想要请求某个接口,但接口返回数据后只更改数据,不刷新UI

这个时候一定要考虑数据同步性的问题。在做日历页的小程序分享需求时,有两个接口:一个接口控制入口是否展示,一个接口负责构建分享content。我在后面请求完第一个接口后,认为我只要更新数据层就好了。可是这样很可能有问题:当入口应该展示了,可是我没有刷新UI,导致入口并没有展示出来!

008 ViewStub如何使用?

需要一个成员变量标识第一次inflate。只有当第一次inflate时,

var viewStub = mRootView.findViewById(R.id.wechat_stub) as? ViewStub
viewStub?.inflate()

后面就不能再inflate了,如果用到这个view,只需要用inflatedId找到这个View就行了。如下所示:

        var viewStub = mRootView.findViewById(R.id.wechat_stub) as? ViewStub
        viewStub?.inflate()
        mRootView.findViewById(R.id.wechat_import).setOnClickListener {
            it.visibility = View.GONE
        }

009 周边游在切换城市时,没有把标志位重置,导致瀑布流展示出问题

当时有这样一个需求,如果当前定位在服务端下发的几个城市中,那就展示瀑布流,否则展示产品列表。我当时是这么做的:同时请求10城接口和瀑布流接口,如果是10城,就把瀑布流隐藏掉。可是这样存在接口谁先返回谁后返回的问题,于是我这边就设置了一个标志位。可是!!在切换城市,需要重新刷新页面的时候,我并没有把这个标志位重置,导致逻辑出错。

 

二、我在编程过程中的犯错总结

001 数组越界

(1)

在线上可能存在一种情况:接口吐出来的数据不足3行,而这里的双重for循环还在按着3乘以3的结构布局。我写这行代码的时候显然已经考虑到了这种情况,只是这只考虑了空指针异常,并没有考虑到数组越界的异常。改进后的代码如下:

经验总结:数组遍历时,除了考虑空指针异常,也应该考虑数组越界异常。

(2)在日常开发中,接口常常会返回给我们一个数组,而这个数组只有一个元素。对于这种异常处理,我常常会直接对get(0)做下判空处理。然而,异常情况下数组元素可能为0啊。这个时候就会报数组越界的错。

002 局部变量赋值错误

(1)在开发周边游首页时,我在页面加载时给成员变量saleCityId进行赋值,

saleCityID = CurrentCityManager.getSaleCityId();

可是在后面某个操作里,我没有去更新这个成员变量的值,导致用到这个变量的url跳转都出现了问题。

经验总结:对于这种情况,没有必要定义成员变量,在用到售卖站城市id时,直接调用CurrentCityManager.getSaleCityId()方法即可。

003 NumberFormatException错误

(1)这个错误是在字符串转化为数字时出现的。

首先,字符串是如上图这样得到的。在这之前都做过异常处理,所以这边就直接转为带有一位小数的字符串。然而,在转化为数字时就会报错!经过反复排查,终于定位到问题!原来,当用户手机语言设置为波兰语时,如上方法转化为的带有一位小数的字符串,是用“,”拼接,如“5,4”。而不是我们能理解的“5.4”。经过查询,波兰语中,就是用逗号连接整数和小数的。如要正确转化,请改成如下代码:

经验总结:不管何时,只要字符串转数字,至少要加Try catch!!

004 小版本迭代时新增代码的问题

在上线前,测试告诉我说给跳转到下个页面的url多加一个字段。于是,我就这样加了。。。

可是,自由行sdp工具化页面url跟团游页面url参数我不是用的一个变量,一个是用的query,一个是用的一个方法getSdpToolQuery。可是当我新增字段的时候,我看到query这个变量,就天真地以为这三个页面用的同一个query,于是就加错了。

经验总结:重读《重构》!自己的编程规范还需要进一步升级!!遇到这种情况,到底该不该用两个query呢?

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值