网络请求
Http的常用请求方式有:
Get&Post:
网络请求中我们常用键值对来传输参数。
JSON
JSON(JavaScript Object Notation)是一种基于文本的数据交换格式。无论你的应用是用哪种开发语言编写的(Java/EE,Ruby,PHP,C#/.Net等等),你都可以使用JSON来通过网络进行数据交互和处理。
JSON是一种简单数据格式,它有三种数据结构:
- 键值对 —— Name/Value (Key/Value)
- 对象 —— Object
- 数组 —— Arrays
用Android原生技术解析JSON:
1、解析JSON对象的API:JsonObject
JSONObject(String json);将Json字符串解析成Json对象;
XxxgetXxx(String name) ;根据name在json对象中得到相应的value。
//获取JSON数据
final String content = response.body().string();
JSONObject jsonObject = null;
try {
//解析JSON对象
jsonObject = new JSONObject(content);
JSONObject result = jsonObject.optJSONObject("result");
final int detailid = result.optInt("detailid");
final String title = result.optString("title");
final String type = result.optString("type");
String c = result.optString("content");
// 封装Java对象
detailModel = new DetailModel(detailid, title, type, c);
System.out.println(detailModel);
handler.post(new Runnable() {
@Override
public void run() {
Log.d("PoetryTag", "detailid:" + detailid + ", title:" + title + ", type:" + type + ", content:" + content);
//显示解析后的数据
tv_title.setText(detailModel.getTitle());
tv_type.setText(detailModel.getType());
tv_content.setText(Html.fromHtml(detailModel.getContent()));
}
});
} catch (JSONException e) {
e.printStackTrace();
}
2、解析Json数组的API:JSONArray
JSONArray(String json);将json字符串解析成json数组;
int length();得到json数组中元素的个数;
XxxgetXxx(int s) ;根据下标得到json数组中对应的元素数据。
private List<PoetryModel> data(String content) {
List<PoetryModel> poetryModels = new ArrayList<>();
try {
//解析json数组
JSONObject jsonObject = new JSONObject(content);
JSONArray jsonArray = jsonObject.optJSONArray("result");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
if (object != null) {
int detailid = object.optInt("detailid");
String name = object.optString("name");
String author = object.optString("author");
// 封装Java对象
PoetryModel poetryModel = new PoetryModel(detailid, name, author);
//显示解析后的数据
poetryModels.add(poetryModel);
Log.d("PoetryTag", "detail:" + detailid + ", name:" + name + ", author:" + author);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return poetryModels;
}
OkHttp
导入Jar包
implementation 'com.squareup.okhttp3:okhttp:3.2.0’
在日常开发中最常用到的网络请求就是GET和POST两种请求方式。
- Requests(请求)
每一个HTTP请求中都应该包含一个URL,一个GET或POST方法以及Header或其他参数,当然还可以含特定内容类型的数据流。 - Responses(响应)
响应则包含一个回复代码(200代表成功,404代表未找到),Header和定制可选的body。
final OkHttpClient client = new OkHttpClient();
public void run(int id) {
Request request = new Request.Builder()
.url("[https://api.jisuapi.com/tangshi/detail?appkey=ccb0bd990f91c687&detailid=](https://api.jisuapi.com/tangshi/detail?appkey=ccb0bd990f91c687&detailid=)" + id)
.get()
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
// ...JSON解析...
}
- 同步&异步
这2个概念仅存在于多线程编程中。
android中默认只有一个主线程,也叫UI线程。因为View绘制只能在这个线程内进行。
所以如果你阻塞了(某些操作使这个线程在此处运行了N秒)这个线程,这期间View绘制将不能进行,UI就会卡。所以要极力避免在UI线程进行耗时操作。
网络请求是一个典型耗时操作。
同步:直接耗时操作阻塞线程直到数据接收完毕然后返回。Android不允许的。
异步:在子线程进行耗时操作,完成后通过Handler将更新UI的操作发送到主线程执行。
使用handler中的post方法:
handler.post(new Runnable() {
@Override
public void run() {
Log.d("PoetryTag", "detailid:" + detailid + ", title:" + title + ", type:" + type + ", content:" + content);
//显示解析后的数据
tv_title.setText(detailModel.getTitle());
tv_type.setText(detailModel.getType());
tv_content.setText(Html.fromHtml(detailModel.getContent()));
}
});
这样处理的话我们就可以不用重写handlerMessage()方法了,适合子线程与主线程进行较为单一的交流。
实例:
MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button bt_get;
private Button bt_post;
private PoetryAdapter adapter;
private RecyclerView recycler;
final OkHttpClient client = new OkHttpClient();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recycler = findViewById(R.id.recycler);
recycler.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false));
bt_get = findViewById(R.id.bt_get);
bt_post = findViewById(R.id.bt_post);
bt_get.setOnClickListener(this);
bt_post.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bt_get:
run();
try {
run();
} catch (Exception e) {
e.printStackTrace();
}
break;
}
}
private void getRequest() {
final Request request = new Request.Builder()
.get()
.tag(this)
.url("https://api.apiopen.top/recommendPoetry")
.build();
new Thread(new Runnable() {
@Override
public void run() {
Response response = null;
try {
response = client.newCall(request).execute();
if (response.isSuccessful()) {
Log.i("WY", "打印GET响应的数据:" + response.body().string());
} else {
throw new IOException("Unexpected code " + response);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
public void run() {
Request request = new Request.Builder()
.url("https://api.jisuapi.com/tangshi/chapter?appkey=ccb0bd990f91c687")
.get()
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
String content = response.body().string();
final List<PoetryModel> poetryModels = data(content);
runOnUiThread(new Runnable() {
@Override
public void run() {
PoetryAdapter adapter = new PoetryAdapter(poetryModels);
recycler.setAdapter(adapter);
adapter.setOnItemClickListener(new PoetryAdapter.OnItemClickListener() {
@Override
public void onItemClick(PoetryModel poetryModel) {
Intent intent = new Intent(MainActivity.this,DetailActivity.class);
intent.putExtra("entity",poetryModel);
startActivity(intent);
}
});
}
});
}
});
}
private List<PoetryModel> data(String content) {
List<PoetryModel> poetryModels = new ArrayList<>();
try {
//解析json数组
JSONObject jsonObject = new JSONObject(content);
JSONArray jsonArray = jsonObject.optJSONArray("result");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
if (object != null) {
int detailid = object.optInt("detailid");
String name = object.optString("name");
String author = object.optString("author");
// 封装Java对象
PoetryModel poetryModel = new PoetryModel(detailid, name, author);
//显示解析后的数据
poetryModels.add(poetryModel);
Log.d("PoetryTag", "detail:" + detailid + ", name:" + name + ", author:" + author);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return poetryModels;
}
}
DetailAcivity:
public class DetailActivity extends AppCompatActivity {
private TextView tv_title;
private TextView tv_type;
private TextView tv_content;
private DetailModel detailModel;
private PoetryModel poetryModel;
private Handler handler = new Handler();
final OkHttpClient client = new OkHttpClient();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
tv_title = findViewById(R.id.tv_title);
tv_type = findViewById(R.id.tv_type);
tv_content = findViewById(R.id.tv_content);
poetryModel = getIntent().getParcelableExtra("entity");
run(poetryModel.getDetailid());
}
public void run(int id) {
Request request = new Request.Builder()
.url("https://api.jisuapi.com/tangshi/detail?appkey=ccb0bd990f91c687&detailid=" + id)
.get()
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
//获取JSON数据
final String content = response.body().string();
JSONObject jsonObject = null;
try {
//解析JSON对象
jsonObject = new JSONObject(content);
JSONObject result = jsonObject.optJSONObject("result");
final int detailid = result.optInt("detailid");
final String title = result.optString("title");
final String type = result.optString("type");
String c = result.optString("content");
// 封装Java对象
detailModel = new DetailModel(detailid, title, type, c);
System.out.println(detailModel);
handler.post(new Runnable() {
@Override
public void run() {
Log.d("PoetryTag", "detailid:" + detailid + ", title:" + title + ", type:" + type + ", content:" + content);
//显示解析后的数据
tv_title.setText(detailModel.getTitle());
tv_type.setText(detailModel.getType());
tv_content.setText(Html.fromHtml(detailModel.getContent()));
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
}
运行结果: