android volley + Gson 获取数据

目录结构

Paste_Image.png
Weather.java

天气数据的抽象

package org.chitarra.tiny.myapplication.bean;
public class Weather {
    private WeatherInfo weatherinfo;
    public WeatherInfo getWeatherinfo() {
        return weatherinfo;
    }
    public void setWeatherinfo(WeatherInfo weatherinfo) {
        this.weatherinfo = weatherinfo;
    }
    public class WeatherInfo {
        private String city;
        private String temp;
        private String time;
        public String getCity() {
            return city;
        }
        public void setCity(String city) {
            this.city = city;
        }
        public String getTemp() {
            return temp;
        }
        public void setTemp(String temp) {
            this.temp = temp;
        }
        public String getTime() {
            return time;
        }
        public void setTime(String time) {
            this.time = time;
        }
    }
}
INetworkError.java

统一抛出网络的所有异常

package org.chitarra.tiny.myapplication.presenter;
public interface INetworkError {
    void error(int errorCode);
}
IWeatherData.java

天气数据的接口

package org.chitarra.tiny.myapplication.presenter;
import org.chitarra.tiny.myapplication.bean.Weather;
public interface IWeatherData {
    void weatherDate(Weather weather);
}
WeatherPresenter.java

获取天气数据,这里把业务逻辑写在了Presenter中,没有再写module

package org.chitarra.tiny.myapplication.presenter;
 
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
 
import org.chitarra.tiny.myapplication.service.GsonRequest;
import org.chitarra.tiny.myapplication.service.VolleySingleton;
import org.chitarra.tiny.myapplication.bean.Weather;
 
import java.util.HashMap;
import java.util.Map;

public class WeatherPresenter
{
    VolleySingleton queue;
    Map<String, String> map;
    INetworkError networkErrorLister;
    IWeatherData weatherDataLister;

    public WeatherPresenter(final INetworkError networkErrorLister, final IWeatherData weatherDataLister, VolleySingleton queue)
    {
        this.networkErrorLister = networkErrorLister;
        this.weatherDataLister = weatherDataLister;
        this.queue = queue;

        map = new HashMap<>();
        map.put("key", "value");

        GsonRequest<Weather> gsonRequest = new GsonRequest<Weather>(Request.Method.POST,
        map,
        "http://www.weather.com.cn/data/sk/101010100.html",
        Weather.class,
        new Response.Listener<Weather>()
        {
           @Override
           public void onResponse(Weather weather)
           {
                weatherDataLister.weatherDate(weather);
           }
        },
        new Response.ErrorListener()
        {
           @Override
           public void onErrorResponse(VolleyError volleyError)
            {
                networkErrorLister.error(0x00);
            }
        });
      queue.addRequestQueue(gsonRequest);
  }
}

上面的post写法其实没有用到, 这个api是通过get请求的,只是为了实验这个写法对不对
在文章后面我会实验一下post请求, 获取服务器上的数据

GsonRequest.java

封装了一下Request

package org.chitarra.tiny.myapplication.service;
 
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import com.google.gson.Gson;
 
import java.io.UnsupportedEncodingException;
import java.util.Map;
 
 
public class GsonRequest<T> extends Request<T>
{
 
    private Response.Listener<T> mListener;
    private Map<String, String> mParams;
    private Gson mGson;
    private Class<T> mClass;
 
    /**
     * @param url
     * @param clazz
     * @param listener
     * @param errorListener
     */
    public GsonRequest(String url, Class<T> clazz, Response.Listener<T> listener,
                       Response.ErrorListener errorListener)
    {
        this(Method.GET, url, clazz, listener, errorListener);
    }
 
    @Override
    protected Map<String, String> getParams() throws AuthFailureError
    {
        if (mParams != null)
        {
            return mParams;
        }
        return super.getParams();
    }
 
    public GsonRequest(int method, Map<String, String> params, String url, Class<T> clazz, Response.Listener listener, Response.ErrorListener errorListener)
    {
        this(Method.POST, url, clazz, listener, errorListener);
        mParams = params;
    }
 
 
    /**
     * @param method
     * @param url
     * @param clazz
     * @param listener
     * @param errorListener
     */
    public GsonRequest(int method, String url, Class<T> clazz, Response.Listener listener, Response.ErrorListener errorListener)
    {
        super(method, url, errorListener);
 
        this.mListener = listener;
        this.mGson = new Gson();
        this.mClass = clazz;
        setTag(listener);
    }
 
    @Override
    protected Response<T> parseNetworkResponse(NetworkResponse response)
    {
        try
        {
            String jsonString = new String(response.data, "utf-8");
 
            return Response.success(mGson.fromJson(jsonString, mClass), HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }
        return null;
    }
 
    @Override
    protected void deliverResponse(T response)
    {
        mListener.onResponse(response);
    }
}

setTag(listener);使用在activity中调用取消请求队列的操作,tag使用了listener作为一个标记

VolleySingleton.java

用单利封装了一下Volley,这里有些疑问,Volley框架会把请求添加到队列中,然后一一去执行,同时我们也不需要为每一个请求都new一个volley的对象,所以我把它封装到了一个单例模式中,创建的时候参数的context传递的是getApplicationContext,保证所有请求都使用一个volley对象,所以我就这样去实现

package org.chitarra.tiny.myapplication.service;
 
import android.content.Context;
 
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
 
public class VolleySingleton
{
    private static VolleySingleton ourInstance;
    private RequestQueue mRequestQuene;
 
    public static synchronized VolleySingleton getInstance(Context context)
    {
        if (ourInstance == null)
        {
            ourInstance = new VolleySingleton(context);
        }
        return ourInstance;
    }
 
    private VolleySingleton(Context context)
    {
        mRequestQuene = Volley.newRequestQueue(context);
    }
 
    public RequestQueue getRequestQuene()
    {
        return this.mRequestQuene;
    }
 
    public <T> void  addRequestQueue(Request<T> request)
    {
        getRequestQuene().add(request);
    }
 
    public void cancelRequest(Object object)
    {
        getRequestQuene().cancelAll(object);
    }
}
DemoActivity.java

在activity中,结合了mvp这么使用了volley

package org.chitarra.tiny.myapplication.view;
 
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
 
import org.chitarra.tiny.myapplication.R;
import org.chitarra.tiny.myapplication.service.VolleySingleton;
import org.chitarra.tiny.myapplication.bean.Weather;
import org.chitarra.tiny.myapplication.presenter.DemoImpl;
import org.chitarra.tiny.myapplication.presenter.INetworkError;
import org.chitarra.tiny.myapplication.presenter.IWeatherData;
import org.chitarra.tiny.myapplication.presenter.WeatherPresenter;
 
public class DemoActivity extends AppCompatActivity implements IWeatherData, INetworkError
{
    VolleySingleton mNetworkQuene;
 
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo);
 
        mNetworkQuene = VolleySingleton.getInstance(getApplicationContext());
 
        new WeatherPresenter(this, this, mNetworkQuene);
        new DemoImpl(this);
    }
 
    @Override
    public void error(int errorCode)
    {
        Log.d("TAG", Thread.currentThread().getName());
        Log.e("TAG", errorCode + "");
    }
 
    @Override
    public void weatherDate(Weather weather)
    {
        Log.d("TAG", Thread.currentThread().getName());
        Weather.WeatherInfo weatherInfo = weather.getWeatherinfo();
        Log.d("TAG", weatherInfo.getCity());
        Log.d("TAG", weatherInfo.getTemp());
        Log.d("TAG", weatherInfo.getTime());
    }
}

这里在回中获取了Weather的对象,然后对对象的数据在ui线程中进行输出
同时也留有了cancel的接口, 用于取消在队列中的请求

DemoImpl.java

是为了实验同时抛出错误, 使用同一个接口

package org.chitarra.tiny.myapplication.presenter;
 
import android.os.Handler;
import android.os.Message;
 
public class DemoImpl
{
    INetworkError networkErrorLister;
 
    Handler myHandler = new Handler(){
        @Override
        public void handleMessage(Message msg)
        {
            networkErrorLister.error(msg.what);
            super.handleMessage(msg);
        }
    };
 
    public DemoImpl(INetworkError networkErrorLister)
    {
        this.networkErrorLister = networkErrorLister;
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                try
                {
                    Thread.sleep(6000);
                } catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
                myHandler.sendEmptyMessage(0x00);
            }
        }).start();
    }
}

这里增加6秒的耗时操作来模拟网络环境,之后再通过handler将结果传到ui线程,同时Volley的到数据的接口也是运行在ui线程中的

测试结果
Paste_Image.png

使用Volley 向服务端post一个数据, 这里面服务器我用了node,至于怎么创建的跟android没什么关系,之后有时间我会写一下如何搭建的这个服务端
Paste_Image.png

Paste_Image.png

图中,服务器能接受到android 端发来的post请求,同时也读取了android端的参数,服务端也返回了一个json,在android端也能解析饿了

代码下载 http://download.csdn.net/detail/u010855902/9409975

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,835评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,900评论 2 383
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,481评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,303评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,375评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,729评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,877评论 3 404
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,633评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,088评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,443评论 2 326
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,563评论 1 339
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,251评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,827评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,712评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,943评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,240评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,435评论 2 348

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,724评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,626评论 18 139
  • Android 异步网络请求框架-Volley 1. 功能介绍 1.1. Volley Volley 是 Goog...
    Brian512阅读 3,878评论 2 40
  • 初到这里 让我见到毛遂自荐的你 腼腆害羞,小心翼翼 告别高中的学习 却不知五点三十仍是你的轨迹 于是开始怀疑 奇葩...
    Edelweiss之夢阅读 129评论 0 1
  • 隐约雷鸣 阴霾天空 但盼风雨来 能留你在此 ;隐约雷鸣 阴霾天空 即使天无雨 我亦留此地 ——万叶集...
    圣纠拉阅读 601评论 0 0