电子市场项目总结(四)

电子市场项目总结(四)

1、网络数据解析的封装


这部分代码没有什么灵活性可言,如果能熟练使用BaseAdapter的封装,这里对网络数据的解析封装相对就非常简单了!

直接从代码入手:

public abstract class BaseProtocol<T> {
    // 这里是复习如何使用enum枚举,因为服务器中对请求有一下几种所以封装起来更方便使用
    public enum Key {
        category("category"), image("image"), recommend("recommend"), subject("subject"),
        detail("detail"), home("home"), app("app"), game("game"), download("download"),
        user("user"), hot("hot");

        String key;

        private Key(String key) {
            this.key = key;
        }

        public String getKey() {
            return this.key;
        }
    }

    private String mKey;

    /**
     * 根据position进行分页查询,
     * 此处的分页查询是因为服务器已经支持分页查询的功能,因此只需要填充对应的position即可,
     * 这里有一点,position在数据的连续的情况下可以直接使用list的总数,
     * 即调用者直接填充已经获取的数据的个数。
     */
    public T getData(int position) {
        mKey = setKey().getKey();

        if (StringUtils.isEmpty(mKey))
            return null;

        mKey = mKey + "?index=" + position + getParams();
        // 先从本地缓存中读取,如果没有读取到才网络加载
        String dataString = readCache(position);

        if (StringUtils.isEmpty(dataString)) {
            dataString = readInternet(position);
        }

        return parseData(dataString);
    }

    /**
     * 提供给子类设置参数
     *
     */
    protected abstract String getParams();

    /**
     * 子类实现数据的解析
     *
     */
    protected abstract T parseData(String dataString);

    /**
     * 子类必须实现key,来确认访问地址
     *
     */
    public abstract Key setKey();


    /**
     * 从网络中获取数据,这里网络的解析在HttpHelper类中被封装好了,直接拿来使用即可,
     * HttpHelper中使用的HttpClient,api23以上需要导入path:sdk\platforms\android-23\optional\org.apache.http.legacy.jar包,当然也可使用其他新的框架来封装。
     */
    private String readInternet(int position) {
        // 获取连接对象
        HttpHelper.HttpResult httpResult = HttpHelper.get(HttpHelper.URL + mKey);
        // 获取json数据
        String string = "";

        if (httpResult != null)
            string = httpResult.getString();

        LogUtils.i(string);

        // 如果非空
        if (!StringUtils.isEmpty(string)) {
            saveCache(string);
        }
        return string;
    }

    /**
     * 保存数据到本地,并添加有效期,添加有效期这里可以有两种方式,
     * 一种是直接添加截止期,读取时判断是否超过截止期,
     * 另一种是添加生成的日期,去读时将读取时间减去生成时间,判断是否超过有效期。
     */
    private void saveCache(String data) {
        String cacheDir = MyApplication.getContext().getExternalCacheDir().getAbsolutePath() + File.separator + "jsondata";

        File file = new File(cacheDir);

        if (!file.exists()) {
            file.mkdirs();
            file.setReadable(true);
            file.setWritable(true);
        }
        FileWriter fileWriter = null;
        try {
            file = new File(file, CommonUtil.data2MD5(mKey, ""));
            if (file.exists()) {
                file.delete();
                file.createNewFile();
                file.setReadable(true);
                file.setWritable(true);
            }
            fileWriter = new FileWriter(file);
            // 写上时间标记
//            fileWriter.write(System.currentTimeMillis()+30*1000*60+"\n"); 自带截止日期
            fileWriter.write(System.currentTimeMillis() + "\n");
            fileWriter.write(data);
            fileWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.close(fileWriter);
        }

    }

    /**
     * 从本地中读取缓存
     */
    private String readCache(int position) {
        String data = "";
        String cacheDir = MyApplication.getContext().getExternalCacheDir().getAbsolutePath() + File.separator + "jsondata" + File.separator + CommonUtil.data2MD5(mKey, "");

        File file = new File(cacheDir);

        BufferedReader br = null;

        if (file.exists()) {
            try {
                br = new BufferedReader(new FileReader(file));
                // 读取日期
                long date = Long.parseLong(br.readLine());
                // 在有效期内才使用
                if (System.currentTimeMillis() - date < 1800000) {
                    String line;
                    while ((line = br.readLine()) != null) {
                        data = data + line;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return data;
    }

}

那么这些完成后,子类该实现的方法有:

  • protected abstract String getParams();// 提供给子类设置参数
  • protected abstract T parseData(String dataString);//子类实现数据的解析逻辑
  • public abstract Key setKey();//子类必须实现key,来确认访问地址

2、开始实现一个Fragment


网络协议也已经封装完成子类只需要完成对网络数据的解析即可,那么开始将封装完成的Protocol、BaseFragment、MyBaseAdapter以及BaseViewHolder结合起来就可以构建一个Fragment的了。
代码如下:

public class AppFragment extends BaseFragment {

    private List<AppInfo> mListData = new ArrayList<>();
    private String tag = "AppFragment";
    private MyListView mMyListView;
    private InnerAdapter mAdapter;
    private AppProtocol mAppProtocol;

    /**
     * 数据的刷新会在fragment绘制之前被调用
     */
    protected State loadData() {
        if(mAppProtocol==null)
            mAppProtocol = new AppProtocol();

        mListData = mAppProtocol.getData(0);
        return checkLoad(mListData);
    }

    /**
        没有使用到监听     
    */
    protected void initListener() {
    // empty
    }

    /**
    完成一个布局的记载,可以直接返回一个listView即可
    */
    public View initSuccessLayout() {
        mMyListView = new MyListView(mActivity);

        mAdapter = new InnerAdapter(mListData);
        mMyListView.setAdapter(mAdapter);

        return mMyListView;
    }

    /**
      我们已经完成BaseAdapter的封装,所以我们只需要提供数据就可以实现数据的加载和展现
    */
    private class InnerAdapter extends MyBaseAdapter<AppInfo>{

        public InnerAdapter(List<AppInfo> mDataList) {
            super(mDataList);
        }

        @Override
        protected List<AppInfo> loadingMore() {
            if(mAppProtocol!=null)
                return mAppProtocol.getData(mListData.size());
            return null;
        }

        @Override
        protected BaseViewHolder<AppInfo> getBaseViewHolder(int position) {
            return new AppHolder();
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值