網(wǎng)絡(luò)請求
Http的常用請求方式有:
Get&Post:
網(wǎng)絡(luò)請求中我們常用鍵值對來傳輸參數(shù)。
JSON
JSON(JavaScript Object Notation)是一種基于文本的數(shù)據(jù)交換格式。無論你的應(yīng)用是用哪種開發(fā)語言編寫的(Java/EE,Ruby插掂,PHP,C#/.Net等等)傀履,你都可以使用JSON來通過網(wǎng)絡(luò)進(jìn)行數(shù)據(jù)交互和處理鸥鹉。
JSON是一種簡單數(shù)據(jù)格式,它有三種數(shù)據(jù)結(jié)構(gòu):
- 鍵值對 —— Name/Value (Key/Value)
- 對象 —— Object
- 數(shù)組 —— Arrays
用Android原生技術(shù)解析JSON:
1余境、解析JSON對象的API:JsonObject
JSONObject(String json)驻呐;將Json字符串解析成Json對象;
XxxgetXxx(String name) 芳来;根據(jù)name在json對象中得到相應(yīng)的value含末。
//獲取JSON數(shù)據(jù)
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);
//顯示解析后的數(shù)據(jù)
tv_title.setText(detailModel.getTitle());
tv_type.setText(detailModel.getType());
tv_content.setText(Html.fromHtml(detailModel.getContent()));
}
});
} catch (JSONException e) {
e.printStackTrace();
}
2、解析Json數(shù)組的API:JSONArray
JSONArray(String json)即舌;將json字符串解析成json數(shù)組答渔;
int length();得到j(luò)son數(shù)組中元素的個數(shù)侥涵;
XxxgetXxx(int s) 沼撕;根據(jù)下標(biāo)得到j(luò)son數(shù)組中對應(yīng)的元素?cái)?shù)據(jù)。
private List<PoetryModel> data(String content) {
List<PoetryModel> poetryModels = new ArrayList<>();
try {
//解析json數(shù)組
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);
//顯示解析后的數(shù)據(jù)
poetryModels.add(poetryModel);
Log.d("PoetryTag", "detail:" + detailid + ", name:" + name + ", author:" + author);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return poetryModels;
}
OkHttp
導(dǎo)入Jar包
implementation 'com.squareup.okhttp3:okhttp:3.2.0’
在日常開發(fā)中最常用到的網(wǎng)絡(luò)請求就是GET和POST兩種請求方式芜飘。
- Requests(請求)
每一個HTTP請求中都應(yīng)該包含一個URL务豺,一個GET或POST方法以及Header或其他參數(shù),當(dāng)然還可以含特定內(nèi)容類型的數(shù)據(jù)流嗦明。 - Responses(響應(yīng))
響應(yīng)則包含一個回復(fù)代碼(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中默認(rèn)只有一個主線程,也叫UI線程诗良。因?yàn)閂iew繪制只能在這個線程內(nèi)進(jìn)行汹桦。
所以如果你阻塞了(某些操作使這個線程在此處運(yùn)行了N秒)這個線程,這期間View繪制將不能進(jìn)行鉴裹,UI就會卡舞骆。所以要極力避免在UI線程進(jìn)行耗時操作钥弯。
網(wǎng)絡(luò)請求是一個典型耗時操作。
同步:直接耗時操作阻塞線程直到數(shù)據(jù)接收完畢然后返回督禽。Android不允許的脆霎。
異步:在子線程進(jìn)行耗時操作,完成后通過Handler將更新UI的操作發(fā)送到主線程執(zhí)行狈惫。
使用handler中的post方法:
handler.post(new Runnable() {
@Override
public void run() {
Log.d("PoetryTag", "detailid:" + detailid + ", title:" + title + ", type:" + type + ", content:" + content);
//顯示解析后的數(shù)據(jù)
tv_title.setText(detailModel.getTitle());
tv_type.setText(detailModel.getType());
tv_content.setText(Html.fromHtml(detailModel.getContent()));
}
});
這樣處理的話我們就可以不用重寫handlerMessage()方法了睛蛛,適合子線程與主線程進(jìn)行較為單一的交流。
實(shí)例:
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響應(yīng)的數(shù)據(jù):" + 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數(shù)組
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);
//顯示解析后的數(shù)據(jù)
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數(shù)據(jù)
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);
//顯示解析后的數(shù)據(jù)
tv_title.setText(detailModel.getTitle());
tv_type.setText(detailModel.getType());
tv_content.setText(Html.fromHtml(detailModel.getContent()));
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
}
運(yùn)行結(jié)果: