代码已经托管到码云上,感兴趣的小伙伴可以下载看看

        https://git.oschina.net/joy_yuan/MobilePlayer

本次的网络资源地址使用的是时光网的api接口,地址如下:  

http://api.m.mtime.cn/PageSubArea/TrailerList.api

效果如下:

手机影音第十三天,xutils3、Glide的使用获取网络图片;下拉、上滑刷新;缓存网络资源_第1张图片


一、Xutils3 的使用

        去github上看详解:https://github.com/wyouflf/xUtils3  

        

xUtils3简介

  • xUtils 包含了orm, http(s), p_w_picpath, view注解, 但依然很轻量级(246K), 并且特性强大, 方便扩展:

    • 稳定的基石AbsTask和统一的回调接口Callback, 任何异常, 即使你的回调方法实现有异常都会进入onError, 任何情况下onFinished总会让你知道任务结束了.

    • 基于高效稳定的orm工具, http模块得以更方便的实现cookie(支持domain, path, expiry等特性)和 缓存(支持Cache-Control, Last-Modified, ETag等特性)的支持.

    • 有了强大的http及其下载缓存的支持, p_w_picpath模块的实现相当的简洁, 并且支持回收被view持有, 但被Mem Cache移除的图片, 减少页面回退时的闪烁..

    • view注解模块仅仅400多行代码却灵活的支持了各种View注入和事件绑定, 包括拥有多了方法的listener的支持.

其他特性

  • 支持超大文件(超过2G)上传

  • 更全面的http请求协议支持(11种谓词)

  • 拥有更加灵活的ORM, 和greenDao一致的性能

  • 更多的事件注解支持且不受混淆影响...

  • 图片绑定支持gif(受系统兼容性影响, 部分gif文件只能静态显示), webp; 支持圆角, 圆形, 方形等裁剪, 支持自动旋转...

  • 从3.5.0开始不再包含libwebpbackport.so, 需要在Android4.2以下设备兼容webp的请使用3.4.0版本.


    1.1、在Android studio中添加xutils3的方法:

       a   在build.gradle里添加依赖

compile 'org.xutils:xutils:3.5.0'

     b    添加权限


       c 新建一个MyApplication类extends Application ,然后重写里面的onCreate()方法,在里面初始化xutils

    

package com.yuanlp.mobileplayer;

import android.app.Application;

import org.xutils.x;

/**
 * Created by 原立鹏 on 2017/7/26.
 */

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        x.Ext.init(this);
        x.Ext.setDebug(BuildConfig.DEBUG); // 是否输出debug日志, 开启debug会影响性能.
    }
}

    d 、利用xutils的注解方法,来实例化布局里的控件

            1)、网络视频也是一个listview,因此主页面与本地视频的主页面类似,



    
    

    


    2)然后就是每个listview的item的布局,有图片和linearlayout

    



    
        
        

    
    

        
        

    


1.2、 利用xutils获取网络资源

            a 利用xutils的x.http().get(params,callback);来获取网络资源,不管获取成功与否,都在callback里有回调方法:

            

Constants.NET_URL="http://api.m.mtime.cn/PageSubArea/TrailerList.api";
RequestParams params=new RequestParams(Constants.NET_URL);
x.http().get(params, new Callback.CommonCallback() {  //回调公用的一个String
    @Override
    public void onSuccess(String result) {
        LogUtil.e("联网成功"+result);

        //解析数据,获取数据并展示adapter
        progressData(result);

        //将获取的数据保存
        CacheUtils.putString(context,Constants.NET_URL,result);

        //设置item点击事件
        listview.setOnItemClickListener(new MyOnItemClickListener());

    }

    @Override
    public void onError(Throwable ex, boolean isOnCallback) {
        LogUtil.e("联网失败"+ex.getMessage());
        nonet.setVisibility(View.VISIBLE); //文本显示没网络数据
        pb_loading.setVisibility(View.GONE);
    }

    @Override
    public void onCancelled(CancelledException cex) {
        LogUtil.e("onCancelled"+cex.getMessage());
    }

    @Override
    public void onFinished() {
        LogUtil.e("onFinished");
    }
});


private void progressData(String result) {
    if (!isloadMore){
        mediaList=progressJson(result);
        showData();
        pb_loading.setVisibility(View.GONE);  //progressbar隐藏
    }else{
        //加载更多,那么就把新的list加入到原有的list中
        ArrayList moreMediaList=progressJson(result);
        mediaList.addAll(moreMediaList);

        //刷新适配器
        netvideoAdap.notifyDataSetChanged();
        isloadMore=false;
        onLoad();

    }
}

private void showData() {
    if (mediaList!=null&&mediaList.size()>0){
        nonet.setVisibility(View.GONE);  //隐藏文本

        netvideoAdap = new NetVideoAdapter(context,mediaList);
        //设置适配器
        listview.setAdapter(netvideoAdap);

        onLoad(); //重新加载listview数据
    }else {
        nonet.setVisibility(View.VISIBLE); //文本显示没网络数据
    }
}

/**
 * 解析json有2中方法:
 * 1、利用系统接口
 * 2、利用第三方接口,如gson,fastjson
 * @param json
 * @return
 */
private ArrayList progressJson(String json) {
    ArrayList mediaItems=new ArrayList<>();
    //利用系统来解析json
    try {
        JSONObject jsonObject=new JSONObject(json);
        JSONArray trailers = jsonObject.optJSONArray("trailers");//利用这个方法,来获取一个数组
        if (trailers!=null&&trailers.length()>0){
           for (int i=0;i 
  


二、Glide的使用

        在build.gradle里添加依赖,然后sync一下就可以了       

compile 'com.github.bumptech.glide:glide:3.6.1'


    在网络资源的adapter里,设置图片的网络资源时,用Glide最好,这样子模拟机与真机里都可以获取到图片。

    

Glide.().load(item.getCoverImg()).into(viewHolder.);


具体的adapter代码如下:

    

package com.yuanlp.mobileplayer.adapter;

import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.yuanlp.mobileplayer.R;
import com.yuanlp.mobileplayer.bean.MediaItem;
import com.yuanlp.mobileplayer.utils.Utils;

import java.util.ArrayList;

/**
 * Created by 原立鹏 on 2017/7/26.
 */

public class NetVideoAdapter extends BaseAdapter {

    private Context context;
    private ArrayList mediaList;
    private Utils utils;
    private static Bitmap bitmap;

    public NetVideoAdapter(Context context, ArrayList mediaList){
        this.context=context;
        this.mediaList=mediaList;


    }

    @Override
    public int getCount() {
        return mediaList.size();
    }

    @Override
    public Object getItem(int position) {
        return mediaList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder=null;
        if (convertView==null){
            View view = LayoutInflater.from(context).inflate(R.layout.netmedialayout, null);
            convertView=view;
            viewHolder=new ViewHolder();
            viewHolder.iv_icon= (ImageView) convertView.findViewById(R.id.iv_icon);
            viewHolder.tv_name= (TextView) convertView.findViewById(R.id.tv_name);
            viewHolder.tv_videotitle= (TextView) convertView.findViewById(R.id.tv_videotitle);


            convertView.setTag(viewHolder);
        }else{
            viewHolder= (ViewHolder) convertView.getTag();
        }

        //得到数据
        MediaItem item=mediaList.get(position);
        viewHolder.tv_name.setText(item.getName());

        viewHolder.tv_videotitle.setText(item.getVideoTitle());
        
        Glide.with(context).load(item.getCoverImg()).into(viewHolder.iv_icon);
       // x.p_w_picpath().bind(viewHolder.iv_icon,item.getCoverImg());
        return convertView;
    }


    /**
     * 公共的控件类,里面包含每一行要显示的控件
     */
    private static class ViewHolder{
        ImageView iv_icon;
        TextView tv_name;
        TextView tv_time;
        TextView tv_size;

        TextView tv_videotitle;
    }
}


三、下拉刷新,xListView 

        在这里下拉刷新我用的是网络上的一个Xlistview,可以到github上下载

        下载好之后,把src文件夹里的XListView 、XListViewFooter、XListViewHeader拷贝到自己的项目里,然后把res里对应的布局文件拷贝过去。

        然后把上面的自定义的网络资源里的布局文件的listview的类,指向我们刚才拷贝的XlistView

        

    当设置好listview的setAdapter后,我们要设置listview的上拉、下拉刷新

        

listview.setPullLoadEnable(true);

listview.setXListViewListener(new MyXListViewListener());

class MyXListViewListener implements XListView.IXListViewListener {

    @Override
    public void onRefresh() {
        getData();

    }

    @Override
    public void onLoadMore() {

        RequestParams params=new RequestParams(Constants.NET_URL);
        x.http().get(params, new Callback.CommonCallback() {  //回调公用的一个String
            @Override
            public void onSuccess(String result) {
                LogUtil.e("联网成功"+result);
                isloadMore=true;
                //解析数据,获取数据并展示adapter
                progressData(result);

                listview.setOnItemClickListener(new MyOnItemClickListener());

            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                LogUtil.e("联网失败"+ex.getMessage());
                isloadMore=false;
                nonet.setVisibility(View.VISIBLE); //文本显示没网络数据
                pb_loading.setVisibility(View.GONE);

            }

            @Override
            public void onCancelled(CancelledException cex) {
                LogUtil.e("onCancelled"+cex.getMessage());
                isloadMore=false;
            }

            @Override
            public void onFinished() {
                LogUtil.e("onFinished");
                isloadMore=false;
            }
        });
    }
}

/**
 * 重新加载adapter里的数据
 */
private void onLoad() {
    listview.stopRefresh();
    listview.stopLoadMore();
    listview.setRefreshTime("更新时间"+getSystemTime());
}


    在这里我们写了listview的上拉下拉监听回调方法。

        a 、 当下拉时,重新去刷新数据,相当于去重新请求该api地址的数据。

        b 、在上拉时,去获取新的数据,放到list里,然后setAdapter。这里由于数据固定,就每次上拉时,把原先的list拷贝一份加进去,相当于2个list的数据。

    


    四、当有网络时,把网络资源保存到本地,断网后,再打开应用可以将资源展现。

        定义一个CacheUtils类,来实现get/set网络资源

        

package com.yuanlp.mobileplayer.utils;

import android.content.Context;
import android.content.SharedPreferences;

/**
 * Created by 原立鹏 on 2017/7/26.
 *
 * 当网络断掉时,之前访问的网络视频资源保存到本地
 */

public class CacheUtils {

    public static void putString(Context context,String key,String values){
        //创建一个私有的文件
        SharedPreferences sharedPreferences=context.getSharedPreferences("yuan",Context.MODE_PRIVATE);
        sharedPreferences.edit().putString(key,values).commit();
    }

    public static String  getString(Context context,String key){
        SharedPreferences sharedPreferences=context.getSharedPreferences("yuan",Context.MODE_PRIVATE);

        return sharedPreferences.getString(key,""); //默认返回空字符串
    }
}


    这样在有网络时,就把数据存到本地

        

/**
 * 获取网络数据
 */
public void getData() {

    RequestParams params=new RequestParams(Constants.NET_URL);
    x.http().get(params, new Callback.CommonCallback() {  //回调公用的一个String
        @Override
        public void onSuccess(String result) {
            LogUtil.e("联网成功"+result);

            //解析数据,获取数据并展示adapter
            progressData(result);

            //将获取的数据保存到本地
            CacheUtils.putString(context,Constants.NET_URL,result);

            //设置item点击事件
            listview.setOnItemClickListener(new MyOnItemClickListener());

        }
        
        。
        。
        。
        。

        当初始化时,回去读取本地视频,如果有,则去读取并展示

@Override
public void initData() {
    super.initData();
    //获取网络数据
    getData();
    LogUtil.e("网络视频页面的数据被初始化了");

    //获取之前有网络时保存的数据
    String jsonResult=CacheUtils.getString(context,Constants.NET_URL);
    //当有本地数据时,去解析本地数据
    if (!TextUtils.isEmpty(jsonResult)){
        progressData(jsonResult);
    }

    listview.setPullLoadEnable(true);

    listview.setXListViewListener(new MyXListViewListener());


}