【Android-业务】业务之让APP在有网无网情况下都能运行

【Android-业务】

一、让APP在有网无网情况下都能运行



前言

甲方:做个简单的APP端OA吧
乙方:好的
项目快交付了......
甲方:没网也要能用
乙方:......

一、分析

简化一下思路:
有网-->用户点击-->APP处理-->访问数据库-->返回结果
所以我们能“秀操作”的地方只有“访问数据库”了。
所以解决方案就是:
当你准备离线时,从服务端的数据库拉取下来相关的数据,保存到本地数据库。
无网操作本地数据库。
到有网的地方,移动端和服务端进行数据同步。

二、业务点

1.同步代码

这个很简单,就是根据个人的权限,直接get数据库相关数据,然后给APP,保存到sqlite。

2.难点:双策略

什么叫“双策略”呢?

比如你有一个“修改个人手机号”的方法setUserPhone,那么这个方法在有网的情况下,毫无疑问就是简单的请求http,然后服务端操作数据库,最后返回结果。

那么无网的情况呢?

还是同样的方法setUserPhone,但是需要另一套操作,这就是“双策略”了。


造个轮子

先来简单的,因为“双策略”很像“接口+不同的实现”,所以我们先做这个(为了更理解后面的封装)。

接口类:

/**
 * <p>
 * 一个接口
 * </p>
 *
 * @author mythS
 * @since 2020/5/14 15:35
 */
public interface JieKou {
    /**
     * 用于测试两种状态的下的接口
     */
    int test();
}

第一种情况的实现类:

/**
 * <p>
 * 接口在1情况下的实现
 * </p>
 *
 * @author mythS
 * @since 2020/5/14 15:38
 */
public class JKShiXian1 implements JieKou {
    @Override
    public int test() {
        return 1;
    }
}

第二种情况的实现类:

/**
 * <p>
 * 接口在2情况下的实现
 * </p>
 *
 * @author mythS
 * @since 2020/5/14 15:38
 */
public class JKShiXian2 implements JieKou {
    @Override
    public int test() {
        return 2;
    }
}

判断以及选择不同的接口实现:

/**
 * <p>
 * 主入口测试效果
 * </p>
 *
 * @author mythS
 * @since 2020/5/14 15:39
 */
public class Test {

    JieKou jieKou;

    public void test(int qingkuang) {
        if (qingkuang == 1) {
            //走1接口
            jieKou = new JKShiXian1();
        }
        if (qingkuang == 2) {
            //走2接口
            jieKou = new JKShiXian2();
        }
        int n = jieKou.test();
        Log.i("提示", "" + n);
    }

}

使用举例:

Test test = new Test();

如果要第二种实现,就这样:

test.test(2);

如果要第一种实现,就这样:

test.test(1);

轮子升华版

首先我们需要明确要做出什么效果:

1、用户继承我的“策略封装类”,需要复写一个自己的“什么情况,用什么策略”的方法(拥有了更广泛的适用性)

2、开放一个api,能够让用户传入“实现类”获取其实例(用户可以在需要的时候,直接取需要的实例)

3、接口的调用不再是用接口本身的名字,而是用自己继承“策略封装类”后子类的实例调用(让程序和接口解耦)

PS:上面的“轮子版”代码,直接放进来用于演示,就不新建新的接口以及实现了。

下面直接上代码,代码最后跟上解释:

策略的封装类(核心):

/**
 * <p>
 * 策略的封装类
 * </p>
 *
 * @author mythS
 * @since 2020/5/15 13:19
 */
abstract class BaseStrategy {

    /**
     * 策略的逻辑
     * 继承这个抽象类,需要个性化实现这个方法
     *
     * @param n   不同情况的标识,比如0是在线1是离线
     * @param <E> 返回接口的实例(复写后一定要换成自己接口的全限定性名)
     *
     * @return 所需求情况下的实例
     */
    public abstract <E> E cur(int n);

    /**
     * 获得实现类实例
     *
     * @param eClass 实现类全限定性名
     */
    protected static <E> E getImpl(Class<?> eClass) {
        String s = getClassFullName(eClass);
        return (E) getImplCur(s);
    }

    /**
     * 全限定名字符串处理
     */
    private static String getClassFullName(Class<?> eClass) {
        String s = eClass.toString();
        if (s.split(" ").length > 1) {
            s = s.split(" ")[1];
        }
        return s;
    }

    /**
     * 利用反射根据类名获得其实例
     */
    private static Object getImplCur(String s) {
        Object o = null;
        try {
            o = Class.forName(s).newInstance();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return o;
    }
}

这个类就是这次“升华版”的核心。总体来说这个类的设计思路为:
通过传进来一个“实现类”的全限定性名,
然后利用反射生成其实例(getImplCur方法)。实例赋值给开放api方法getImpl。

定义一个抽象方法cur,参数就是不同情况的标识,用户自己拟定,比如在线是0,离线是1,根据自己的业务拟定。

这样用户继承这个“父类”的时候,重写这个方法,根据标识,利用开放api方法getImpl,获得需要的“实现类”就能完成我们的预想了。

下面举例说明怎么使用:

第一步,上代码:

/**
 * <p>
 * 举例使用策略
 * </p>
 *
 * @author mythS
 * @since 2020/5/15 15:08
 */
public class TestStrategy extends BaseStrategy {
    @Override
    public JieKou cur(int n) {
        //1也就是在线时,需要JKShiXian1的实现
        if (n == 1) {
            return getImpl(JKShiXian1.class);
        } else {
            return getImpl(JKShiXian2.class);
        }
    }

}

就是简单的创建一个子类,继承BaseStrategy,然后根据自己的业务复写cur方法,
我这里是假设在线时需要JKShiXian1的实现,离线时需要JKShiXian2的实现。n为1代表在线。

在具体需要使用的地方,实例化子类TestStrategy为u,然后直接u.cur(2).test()就能获得JKShiXian2的实现效果。
代码:

TestStrategy u = new TestStrategy();
Log.i("提示", "" + u.cur(1).test());

补充:
如果觉得上面两行太麻烦,还需要new对象,可以在TestStrategy写一个静态方法cur1,
然后内容和复写cur方法时里面的内容一样,然后注掉cur内容,返回个null(就是不用这个了)
然后在需要调用的地方直接TestStrategy.cur1即可。
这也是上面说的”需要实现的效果2“的开发api的好处,使用者比较自由。

总结

关于这个令人无语的业务,确实在实际开发中遇到了(人生真实处处有“惊喜”)。
当然了,实际解决肯定不是这么简单,实际需要考虑的方方面面有很多,代码很庞大,但是因为代码需要保密,只能写这样一个简单例子,帮助遇到同类问题的朋友,能有个思路。
如果觉得有疑惑、有类似业务或者我写的有问题,不妨留言,讨论一下。
当然,如果能顺手给个赞,在下感激不已。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值