Square 之 Retrofit 使用详解

Android 网络请求框架

如有问题请先参考 一下链接

http://square.github.io/retrofit/

1)  OkHttp  :回调方法 在子线程中执行
2)  Retrofit

使用 okHttp

okHttp 在android 中使用相对较少,异步接口回调处,方法不在ui线程中执行。
而在retrofit 的底层中已经引进了 okHttp ,okHttp 与andorid 并没有什么关系,亦可在 java 中使用

使用方式 代码如下 内含 pull 数据解析 :
 package com.jash.okhttpdemo;

    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.widget.Toast;

    import org.xmlpull.v1.XmlPullParser;
    import org.xmlpull.v1.XmlPullParserException;
    import org.xmlpull.v1.XmlPullParserFactory;

    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;

    import okhttp3.Call;
    import okhttp3.Callback;
    import okhttp3.MediaType;
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.RequestBody;
    import okhttp3.Response;
    import okhttp3.ResponseBody;

    public class MainActivity extends AppCompatActivity implements Callback {

        private static final String TAG = MainActivity.class.getSimpleName();
        private Call call;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            OkHttpClient client = new OkHttpClient();
            RequestBody requestBody = RequestBody.create(MediaType.parse("text/html"), "?mod=rss");
            Request request = new Request.Builder().url("http://www.inexus.co/portal.php").post(requestBody).build();
            call = client.newCall(request);
            //同步请求
    // Response response = call.execute();
            //异步请求
            call.enqueue(this);
        }

        @Override
        protected void onDestroy() {
            super.onDestroy();
            call.cancel();
        }

        /** * 失败回调,是在非UI线程中执行 * @param call * @param e */
        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }

        /** * 成功回调,是在非UI线程中执行 * @param call * @param response * @throws IOException */
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            Log.d(TAG, "onResponse: " + Thread.currentThread().getId());
            Log.d(TAG, "onResponse: " + Thread.currentThread().getName());
            if (response.code() == 200) {
                ResponseBody body = response.body();
                //字节数组
    // body.bytes();
                //字符集为UTF-8的字符串
    // String string = body.string();
                try {
                    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
                    XmlPullParser parser = factory.newPullParser();
                    parser.setInput(body.charStream());
                    List<RssItem> list = new ArrayList<>();
                    while (parser.next() != XmlPullParser.END_DOCUMENT){
                        switch (parser.getEventType()){
                            case XmlPullParser.START_TAG:
                                switch (parser.getName()){
                                    case "item":
                                        list.add(new RssItem());
                                        break;
                                    case "title":
                                        if (!list.isEmpty()) {
                                            list.get(list.size() - 1).setTitle(parser.nextText());
                                        }
                                        break;
                                        case "link":
                                        if (!list.isEmpty()) {
                                            list.get(list.size() - 1).setLink(parser.nextText());
                                        }
                                        break;
                                    case "category":
                                        if (!list.isEmpty()) {
                                            list.get(list.size() - 1).setCategory(parser.nextText());
                                        }
                                        break;
                                    case "author":
                                        if (!list.isEmpty()) {
                                            list.get(list.size() - 1).setAuthor(parser.nextText());
                                        }
                                        break;

                                }
                                break;
                        }
                    }
                    Log.d(TAG, "onResponse: ");
                } catch (XmlPullParserException e) {
                    e.printStackTrace();
                }
            }
        }
    }







使用Retrofix :25 minutes 普通数据 json 数据xml delete 都可

简介: retrofit 底层使用,okHttp

使用 接口,Retrofit开启 实体类注解:

如果解析数据 用到 gson 的话 可以直接导入 gosn 的转换器

http header 头请求数据

 @Headers("")       // 部分网络请求需要设置 Headers 在此设置
 @GET("portal.php")  get中数据 为文件地址 
 Call<String> getXML(@Query("mod") String mod);// 方法参数
 @Query 

注意

如果使用到 Post 并且使用到 String 的时候 需要 添加
@FormUrlEncoded
1) 新建interface 内容格式如下:

 @GET("portal.php") // post  请求的话 直接在这改 就行 delete copy  请求都可以做
 @Headers({"apikey:123"})  //可以加http 头请求数据
 Call<String> getXML(@Query("mod") String mod);// 这种方式 就会 key value 的形式拼接下去




2) 调用处  : 
    a) 构建 Retrofit 对象

    b)   // 动态实现接口的一种方式 把接口实例化出来一个对象
        Service service = retrofit.create(Service.class);
c)开启异步
    // call = service.getXML("rss");
    // 建立实体类的时候 注意 实体类最好加上注解
     package com.example.liyang.retrofituse;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.ArrayList;

import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Converter;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class MainActivity extends AppCompatActivity implements Callback<String> {

    private Call<String> call;
    private ListView lv;
    private ItemAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv = (ListView) findViewById(R.id.main_list);
        adapter = new ItemAdapter(this,new ArrayList<Item>());
        lv.setAdapter(adapter);



        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://www.tngou.net")

// create 的参数为 gosn 的实体类 没有特殊要求的话 直接使用 无参的就可以
                // 有要求的话 重写下就行
                .addConverterFactory(GsonConverterFactory.create())
 // Response 转换成为 type 类型
//@Override
// public Converter<ResponseBody, ?> 

//responseBodyConverter(Type type, Annotation[] annotations, 

//Retrofit retrofit) {

// if (type.equals(String.class)) {

// return new Converter<ResponseBody, String>() {

// //把传入的这个 ResponseBody 转换成我们需要的数据
// 这里指的是 String 实体类的话 再将String 解析即可
// @Override
// public String convert(ResponseBody value) throws IOException {
//
 //注意这个地方是 string 不是 toStirng
// return value.string();
// }
// };
// }
//
 // 其他的使用 父类的方法 即可 其实 父类的方法 返回的是一个 空

// return super.responseBodyConverter(type, annotations, retrofit);
// }
// })

                .build();

        // 动态实现接口的一种方式 把接口实例化出来一个对象
        Service service = retrofit.create(Service.class);

        // 调用里边的方法
       // call = service.getXML("rss");
        // 建立实体类 注意 实体类最好加上注解
        Call<Tngou> json = service.getJson();

        json.enqueue(new Callback<Tngou>() {
            @Override
            public void onResponse(Call<Tngou> call, Response<Tngou> response) {
                Tngou body = response.body();
                Log.d("MMM", "onResponse: "+body);

            }

            @Override
            public void onFailure(Call<Tngou> call, Throwable t) {

            }
        });

        // 同步方法 不可以在主线程中执行 使用很少
// try {
// call.execute();
// } catch (IOException e) {
// e.printStackTrace();
// }

        // 异步请求方法 这几把单词啥意思
      // call.enqueue(this);


    }

    /** * 在ui 线程中执行 * @param call * @param response */
    @Override
    public void onResponse(Call<String> call, Response<String> response) {

        // 返回值是 String 因为我们之前设置的是 String 其实它可以是任意类型
        String body = response.body();
        Log.d("MMM", "onResponse: "+body);
    }


    // 在页面不展示的时候 同事把这个停下来
    @Override
    protected void onDestroy() {
        super.onDestroy();
        call.cancel();
    }

    /** * 在ui线程 中执行 * @param call * @param t */
    @Override
    public void onFailure(Call<String> call, Throwable t) {

    }
}
3) 实体类 解析数据时 最好添加注解 如下: 

@SerializedName("id")
private long id;
@SerializedName("title")
private String title;

使用retrofit xml 转换器解析

        主流两种数据格式,json与 xml 数据,json 市场 > xml ,当多数论坛依旧使用xml数据,比如我访问网页时的 rss 格式 (很多博客论坛都提供了 rss 格式,需先得到其rss文件的地址) http://bbs.goodprogrammer.org/forum.php?mod=rss&fid=43 

    对rss,xml 文件做解析 规整数据 之后重新 发布 ,使用 retrofit 的自带的xml的转换器

    ① Interface   // 请求方式 请求头  参数
    ② Retrofit 对象构建 开启异步操作
    ③ 实体类 创建 属性注解  数组类型节点 注解 解析

注意:xml 解析必须写注解 为了 混淆的时候 不出错
实体类上解析的高匹配模式必须要关了
@Root(name = “channel”,strick = false )
若解析xml的开始节点 不是根节点的话 如下书写 :
gradle 文件中添加依赖库

 compile ('com.squareup.retrofit2:converter-simplexml:2.0.1'){
        exclude module: 'stax-api'
    }
package com.jash.retrofitxmldemo;

import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Path;
import org.simpleframework.xml.Root;

import java.util.List;

/** * Created by jash on 16-4-11. */
@Root(name = "channel", strict = false)
public class Channel {
    @Element(name = "title")
    @Path("channel")
    private String title;
    @ElementList(name = "item", type = Item.class, inline = true)
    @Path("channel")
    private List<Item> list;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public List<Item> getList() {
        return list;
    }

    public void setList(List<Item> list) {
        this.list = list;
    }
}

你可能感兴趣的:(retrofit)