http://square.github.io/retrofit/
1) OkHttp :回调方法 在子线程中执行
2) Retrofit
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();
}
}
}
}
简介: retrofit 底层使用,okHttp
如果解析数据 用到 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;
主流两种数据格式,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;
}
}