目次
走行結果:
1. okhttp の概要
OkHttp は、ネットワーク リクエストを行うために Android アプリケーションで一般的に使用されるオープン ソース HTTP クライアント ライブラリです。OkHttp の一般的なクラスとメソッドの一部を次に示します。
1.OkHttpClient クラス:
OkHttpClient は OkHttp ライブラリのコア クラスであり、HTTP 要求のクライアントを作成および構成するために使用されます。接続タイムアウト、読み取りおよび書き込みタイムアウト、インターセプターなどのさまざまな設定および構成オプションが提供されます。
一般的に使用される方法:
-
newBuilder()
: OkHttpClient オブジェクトを構成および構築するための新しい OkHttpClient.Builder インスタンスを作成します。 -
addInterceptor(Interceptor interceptor)
:リクエストの送信時と応答の受信時にリクエストを処理するインターセプターを追加します。たとえば、インターセプターを使用して、リクエストの認証、ログ記録、データの変換などの操作を実行できます。 -
connectTimeout(long timeout, TimeUnit unit)
:接続タイムアウトを設定します。時間値と時間単位を指定して、サーバーへの接続の最大時間を制限できます。 -
readTimeout(long timeout, TimeUnit unit)
:読み取りタイムアウトを設定します。時間値と時間単位を指定して、サーバーからのデータ読み取りの最大時間を制限できます。 -
writeTimeout(long timeout, TimeUnit unit)
:書き込みタイムアウトを設定します。時間値と時間単位を指定して、サーバーへのデータ書き込みの最大時間を制限できます。 -
retryOnConnectionFailure(boolean retry)
:失敗した接続要求を再試行するかどうかを設定します。デフォルトでは、OkHttpClient はリクエストを自動的に再試行しますが、このメソッドを使用して再試行を無効にすることができます。 -
followRedirects(boolean followRedirects)
:リダイレクトを自動的にたどるかどうかを設定します。デフォルトでは、OkHttpClient は自動的にリダイレクトに従いますが、この方法で自動リダイレクトを無効にすることができます。 -
cache(Cache cache)
:キャッシュを設定します。Cache オブジェクトを渡すと、ネットワーク要求の応答データをキャッシュできます。 -
dispatcher(Dispatcher dispatcher)
:ディスパッチャスケジューラを設定します。カスタム Dispatcher オブジェクトを渡して、同時リクエストの数とスレッド プールの動作を制御できます。 -
proxy(Proxy proxy)
:プロキシサーバーを設定します。ターゲット サーバーへのリクエストをプロキシするために使用される Proxy オブジェクトを指定できます。
2. リクエストクラス:
Request クラスは、HTTP リクエストを構築するために使用されます。Request.Builder を通じて Request オブジェクトを作成し、URL、リクエスト メソッド (GET、POST など)、リクエスト ヘッダー、リクエスト本文などを設定できます。
一般的に使用される方法:
-
newBuilder()
: Request オブジェクトを構築および構成するための新しい Request.Builder インスタンスを作成します。 -
url(String url)
:要求された URL アドレスを設定します。文字列型の URL アドレスをパラメータとして渡すことができます。 -
method(String method, RequestBody body)
:リクエストのHTTPメソッドとリクエストボディを設定します。リクエストの HTTP メソッド (GET、POST、PUT など) とリクエスト本文の RequestBody オブジェクトを指定できます。 -
header(String name, String value)
:リクエストヘッダーを追加します。このメソッドを使用してカスタム リクエスト ヘッダー パラメーターを追加できます。パラメーター名とパラメーター値を指定する必要があります。 -
headers(Headers headers)
:リクエストヘッダーの収集を設定します。このメソッドを使用すると、複数のリクエスト ヘッダーを一度に設定できますが、Headers オブジェクトを渡す必要があります。 -
cacheControl(CacheControl cacheControl)
:キャッシュ制御ポリシーを設定します。CacheControl オブジェクトを渡して、リクエストのキャッシュ動作を制御できます。 -
tag(Object tag)
:要求されたラベルを設定します。後続の操作でリクエストを識別および識別するために、タイプ Object のラベルを渡すことができます。 -
build()
: Request オブジェクトを構築します。構成が完了したら、このメソッドを使用して最終的な Request オブジェクトを構築します。
3. 応答クラス:
Response クラスは HTTP 応答を表します。HTTP リクエストを送信した後、Response オブジェクトを通じてサーバーから返されるステータス コード、応答ヘッダー、応答本文などの応答情報を取得できます。
一般的に使用される方法:
-
code()
: HTTPレスポンスのステータスコードを取得します。HTTP 応答のステータス コードを表す整数値を返します。 -
message()
: HTTPレスポンスのステータスメッセージを取得します。HTTP 応答のステータス メッセージを表す文字列を返します。 -
body()
: HTTP レスポンスのレスポンスボディを取得します。応答固有のデータを取得および処理するための ResponseBody オブジェクトを返します。 -
headers()
: HTTP レスポンスのレスポンスヘッダを取得します。応答ヘッダー情報の取得と処理に使用される Headers オブジェクトを返します。 -
isSuccessful()
: HTTP 応答が成功したかどうかを判断します。HTTP 応答が成功したかどうかを示すブール値 (ステータス コード 200 ~ 299) を返します。 -
cacheResponse()
:キャッシュされた HTTP レスポンスを取得します。リクエストがキャッシュを使用しており、対応するキャッシュされた応答がある場合は、Response オブジェクトが返されます。それ以外の場合は、null が返されます。 -
networkResponse()
:ネットワークから HTTP レスポンスを取得します。リクエストがネットワーク経由で送信され、対応するネットワーク応答がある場合は Response オブジェクトが返され、それ以外の場合は null が返されます。 -
priorResponse()
:前回のHTTPレスポンスを取得します。リクエストに以前の HTTP レスポンスが関連付けられている場合は Response オブジェクトを返し、そうでない場合は null を返します。 -
request()
:この HTTP 応答に関連付けられたリクエストを取得します。この応答に関連付けられたリクエストを表す Request オブジェクトを返します。
4. クラスを呼び出す:
Call クラスは、非同期 HTTP 要求タスクを表します。OkHttpClient の newCall メソッドを通じて Call オブジェクトを作成し、次に enqueue メソッドを使用して非同期リクエストを送信し、コールバック関数を通じて応答結果を処理します。
一般的に使用される方法:
-
execute()
: HTTP リクエストを同期的に実行し、Response オブジェクトを返します。このメソッドは、完全な応答結果が取得されるまで現在のスレッドをブロックします。 -
enqueue(Callback callback)
: HTTP リクエストを非同期に実行し、コールバック関数を通じて結果を受け取ります。このメソッドは、リクエストをリクエスト キューに入れてバックグラウンド スレッドで実行し、実行完了後、Callback インターフェイスのコールバックを通じて結果を返します。 -
cancel()
: HTTP リクエストをキャンセルします。HTTP リクエストが完了していない場合は、このメソッドを呼び出して進行中のリクエストをキャンセルできます。 -
isExecuted()
: HTTP リクエストが実行されたかどうかを判断します。HTTP リクエストが実行されたかどうかを示すブール値を返します。 -
isCanceled()
: HTTP リクエストがキャンセルされたかどうかを確認します。HTTP リクエストがキャンセルされたかどうかを示すブール値を返します。 -
timeout()
:タイムアウト設定を取得します。接続、読み取り、書き込みのタイムアウトを取得および設定するために使用される Timeout オブジェクトを返します。 -
request()
:この通話に関連付けられたリクエストを取得します。この Call に関連付けられた HTTP リクエストを表す Request オブジェクトを返します。 -
clone()
: Call オブジェクトのコピーを作成します。元の Call オブジェクトと同じ構成およびリクエスト情報を共有する新しい Call オブジェクトを返します。
5. インターセプターインターフェイス:
インターセプター インターフェイスは、HTTP リクエストと応答をインターセプトして処理するために使用できます。カスタム インターセプターを実装して、リクエストの変更、リクエスト ヘッダーの追加、ログの記録などを行うことができます。
一般的に使用される方法:
-
Response intercept(Chain chain)
:リクエストとレスポンスをインターセプトして処理します。このメソッドは、Chain オブジェクトをパラメータとして受け取ります。これにより、リクエスト情報が取得され、次のインターセプタが実行されるか、実際のネットワーク リクエストが開始されます。 -
interface Chain
:インターセプター チェーン内のリンクを表します。リクエストと応答を渡し、インターセプターの実行プロセスを制御するために使用されます。Chain インターフェイスには次のメソッドがあります。
Connection connection()
: 現在のインターセプタ チェーンの接続オブジェクトを取得します。Request request()
: 現在のインターセプタ チェーンのリクエスト オブジェクトを取得します。Response proceed(Request request)
: 次のインターセプタを実行し、最終応答結果を返します。
6. FormBody クラス:
FormBody クラスは、フォームの形式でリクエスト本文を構築するために使用される OkHttp ライブラリ内のクラスです。フォームフィールドと値を追加し、最終的なリクエスト本文データを生成するメソッドを提供します。
一般的に使用される方法:
-
add(String name, String value)
:フォームフィールドと値を追加します。このメソッドを複数回呼び出して、複数のフォーム フィールドと対応する値を追加できます。 -
encodedName(int index)
:エンコードされたフォームフィールド名を取得します。インデックス値を渡し、対応する位置にあるエンコードされたフォーム フィールド名を返します。 -
encodedValue(int index)
:エンコードされたフォームフィールド値を取得します。インデックス値を渡し、対応する位置にあるエンコードされたフォーム フィールド値を返します。 -
name(int index)
:エンコードされていないフォームフィールド名を取得します。インデックス値を渡し、対応する位置にあるエンコードされていないフォーム フィールド名を返します。 -
value(int index)
:エンコードされていないフォームフィールド値を取得します。インデックス値を渡し、対応する位置にあるエンコードされていないフォーム フィールドの値を返します。 -
size()
:フォームフィールドの数を取得します。フォームフィールドの数を表す整数値を返します。 -
contentType()
: リクエストボディのメディアタイプを取得します。リクエスト本文のメディア タイプを示す MediaType オブジェクトを返します。デフォルトは「application/x-www-form-urlencoded」です。 -
contentLength()
:リクエストボディの長さを取得します。リクエスト本文の長さをバイト単位で表すlong値を返します。 -
toString()
: FormBody を文字列に変換します。FormBody の内容を表す文字列を返します。
7. MultipartBody クラス:
MultipartBody クラスは、マルチパート リクエスト本文を構築するために OkHttp ライブラリで使用されるクラスです。これにより、テキスト、ファイルなどの複数の異なるタイプのデータを 1 つのリクエストに含めることができます。
一般的に使用される方法:
-
create(MediaType type, RequestBody... parts)
: MultipartBody オブジェクトを作成します。メディア タイプと複数の RequestBody インスタンスを渡す必要があります。 -
type()
:リクエストボディのメディアタイプを取得します。リクエスト本文のメディア タイプを示す MediaType オブジェクトを返します。デフォルトは「multipart/form-data」です。 -
boundary()
:境界文字列を取得します。リクエスト本文の境界文字列を表す文字列を返します。 -
contentType()
:リクエストボディの完全なメディアタイプを取得します。メディア タイプと境界文字列を含む、リクエスト本文の完全なメディア タイプを表す文字列を返します。 -
parts()
:リクエストボディのさまざまな部分を取得します。リクエスト本文のすべての部分を表す List<RequestBody> を返します。 -
writeTo(BufferedSink sink)
: MultipartBody をバッファに書き込みます。リクエスト本文にデータを書き込むには、BufferedSink オブジェクトを渡す必要があります。 -
contentLength()
:リクエストボディの長さを取得します。リクエスト本文の長さをバイト単位で表すlong値を返します。 -
addPart(Headers headers, RequestBody body)
:リクエスト本文にセクションを追加します。カスタム リクエスト ヘッダー Headers オブジェクトおよび対応する RequestBody インスタンスを渡すことができます。 -
addFormDataPart(String name, @Nullable String filename, RequestBody body)
:リクエスト本文にフォームデータセクションを追加します。フィールド名 name、オプションのファイル名 filename、および RequestBody インスタンスを渡す必要があります。 -
addFormDataPart(String name, @Nullable String filename, MediaType contentType, ByteString content)
:リクエスト本文にフォームデータセクションを追加します。フィールド名 name、オプションのファイル名 filename、メディア タイプ contentType およびコンテンツ content を渡す必要があります。
8. WebSocket クラス:
WebSocket クラスは、WebSocket 通信に使用されます。サーバーへの WebSocket 接続を確立して、双方向に通信できます。
一般的に使用される方法:
-
request()
:この WebSocket に関連付けられたリクエストを取得します。この WebSocket に関連付けられた HTTP リクエストを表す Request オブジェクトを返します。 -
queueSize()
:送信するメッセージキューのサイズを取得します。メッセージ キュー内の送信されるメッセージの数を表す整数値を返します。 -
send(String text)
:テキストメッセージを送信します。文字列タイプのメッセージコンテンツを渡し、それをテキストメッセージとしてサーバーに送信できます。 -
send(ByteString bytes)
:バイナリメッセージを送信します。ByteString オブジェクトを渡して、バイナリ メッセージとしてサーバーに送信できます。 -
close(int code, String reason)
: WebSocket 接続を閉じます。整数のシャットダウン コード (通常のシャットダウンの場合は 1000 など) と文字列のシャットダウン理由を渡して、シャットダウン フレームをサーバーに送信し、WebSocket 接続を閉じることができます。 -
cancel()
: WebSocket接続を解除します。WebSocket 接続が閉じられていない場合は、このメソッドを呼び出して接続をキャンセルできます。 -
send(Request request, WebSocketListener listener)
:指定されたリクエストの WebSocket メッセージを送信します。Request オブジェクトと WebSocketListener オブジェクトを渡し、サーバーにリクエストを送信し、WebSocketListener を通じてコールバック処理の結果をリッスンできます。 -
addListener(WebSocketListener listener)
: WebSocket イベント リスナーを追加します。WebSocketListener オブジェクトを渡して、WebSocket 接続ステータス、メッセージ受信、その他のイベントを監視できます。 -
removeListener(WebSocketListener listener)
: WebSocket イベント リスナーを削除します。WebSocketListener オブジェクトを渡して、WebSocket リスナー リストから削除できます。
2.okhttpの使い方
1. 依存関係を追加します。
プロジェクトの build.gradle ファイルに OkHttp 依存関係を追加します。
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
2. OkHttpClient オブジェクトを作成します。
new OkHttpClient()
OkHttpClient インスタンスを作成する と、HTTP リクエストの送信に使用されます。
OkHttpClient client = new OkHttpClient();
3. リクエスト オブジェクトを作成します。
Request.Builder
リクエスト オブジェクトを構築し、URL アドレス、リクエスト ヘッダー、リクエスト本文、およびその他の関連情報を指定する ために使用します。
Request request = new Request.Builder()
.url("https://example.com/api")
.header("Content-Type", "application/json")
.post(RequestBody.create(MediaType.parse("application/json"), jsonBody))
.build();
4. 同期リクエストを送信します。
client.newCall(request).execute()
同期リクエストを送信し、Response オブジェクトを取得する ために使用します。
try (Response response = client.newCall(request).execute()) {
// 处理响应结果
if (response.isSuccessful()) {
String responseBody = response.body().string();
// ...
} else {
// 请求失败处理
}
} catch (IOException e) {
// IO异常处理
}
5. 非同期リクエストを送信する
client.newCall(request).enqueue(Callback)
非同期リクエストを送信し、Callback コールバックを通じて応答結果を処理する ために使用します。
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 请求失败处理
}
@Override
public void onResponse(Call call, Response response) throws IOException {
// 处理响应结果
if (response.isSuccessful()) {
String responseBody = response.body().string();
// ...
} else {
// 请求失败处理
}
}
});
上記の例では、最初に OkHttpClient オブジェクトを作成し、Request.Builder を使用してリクエスト オブジェクトを構築しました。その後、オプションで同期または非同期リクエストを送信できます。同期リクエストの場合は、execute()
メソッドを直接呼び出して応答結果を処理します。非同期リクエストの場合は、enqueue(Callback)
メソッドを使用し、Callback コールバックを通じて応答結果を処理します。
リクエストを処理した後は、メモリ リークを避けるために、Response オブジェクトのリソースを閉じることに注意する必要があります。
3. okhttp の例
次の例は、Guo Lin マスターが作成したコードの最初の行にある、Kuou Weather Network に地名を要求するコードです。
地方の JSON データ形式:
都市の json データ形式:
http://guolin.tech/api/china/16
郡の json データ形式:
主な活動:
package com.example.okhttpdemo;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.okhttpdemo.Bean.City;
import com.example.okhttpdemo.Bean.County;
import com.example.okhttpdemo.Bean.Province;
import org.litepal.LitePal;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
import okhttp3.internal.Util;
public class MainActivity extends AppCompatActivity {
public static final int CURRENT_PAGE_PROVINCE = 0;
public static final int CURRENT_PAGE_CITY = 1;
public static final int CURRENT_PAGE_COUNTY = 2;
private List<Province> mProvinces;
private List<City> mCities;
private List<County> mCounties;
private TextView titleTV;
private Button backBtn;
private ListView mListView;
private List<String> mListData = new ArrayList<>();
private ArrayAdapter<String> mAdapter;
private ProgressDialog progressDialog;
private int currentPage;
private Province mCurrentProvince;
private City mCurrentCity;
private County mCurrentCounty;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LitePal.initialize(this);
initView();
}
private void initView() {
mListView = findViewById(R.id.list_view);
backBtn = findViewById(R.id.back_button);
titleTV= findViewById(R.id.title_text);
backBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (currentPage==CURRENT_PAGE_COUNTY){
queryCities();
}else if(currentPage == CURRENT_PAGE_CITY){
queryProvinces();
}
}
});
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (currentPage){
case CURRENT_PAGE_PROVINCE:
mCurrentProvince = mProvinces.get(position);
queryCities();
break;
case CURRENT_PAGE_CITY:
mCurrentCity = mCities.get(position);
queryCounty();
break;
case CURRENT_PAGE_COUNTY:
mCurrentCounty = mCounties.get(position);
Toast.makeText(MainActivity.this,"点击了"+mCurrentProvince.getProvinceName()+mCurrentCity.getCityName()+mCurrentCounty.getCountyName(),Toast.LENGTH_LONG).show();
break;
}
}
});
mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, mListData);
queryProvinces();
mListView.setAdapter(mAdapter);
}
private void queryProvinces(){
titleTV.setText("中国");
backBtn.setVisibility(View.GONE);
// 从数据库中找
mProvinces = LitePal.findAll(Province.class);
if (mProvinces.size()>0){
mListData.clear();
for (Province province:mProvinces){
mListData.add(province.getProvinceName());
}
mAdapter.notifyDataSetChanged();
currentPage = CURRENT_PAGE_PROVINCE;
}else {
String url = "http://guolin.tech/api/china";
queryFromServer(url,CURRENT_PAGE_PROVINCE);
}
}
private void queryFromServer(String url, int type) {
showProgressDialog();
HttpTool.sendOkhttpRequest(url, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
runOnUiThread(new Runnable() {
@Override
public void run() {
closeProgressDialog();
Toast.makeText(MainActivity.this,"加载失败!!!",Toast.LENGTH_LONG).show();
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
boolean result = false;
switch (type){
case CURRENT_PAGE_PROVINCE:
result = Utility.handleProvinceResponse(response.body().string());
break;
case CURRENT_PAGE_CITY:
result = Utility.handleCitiesResponse(response.body().string(),mCurrentProvince.getId());
break;
case CURRENT_PAGE_COUNTY:
result = Utility.handleCountyResponse(response.body().string(),mCurrentCity.getId());
break;
}
if (result){
runOnUiThread(new Runnable() {
@Override
public void run() {
closeProgressDialog();
switch (type){
case CURRENT_PAGE_PROVINCE:
queryProvinces();
break;
case CURRENT_PAGE_CITY:
queryCities();
break;
case CURRENT_PAGE_COUNTY:
queryCounty();
break;
}
}
});
}
}
});
}
private void queryCounty() {
titleTV.setText(mCurrentCity.getCityName());
backBtn.setVisibility(View.VISIBLE);
// 从数据库中找
mCounties = LitePal.where("cityid=?",String.valueOf(mCurrentCity.getId())).find(County.class);
if (mCounties.size()!=0){
mListData.clear();
for (County county:mCounties){
mListData.add(county.getCountyName());
}
mAdapter.notifyDataSetChanged();
currentPage = CURRENT_PAGE_COUNTY;
}else {
int provinceCode = mCurrentProvince.getProvinceCode();
int citiCode = mCurrentCity.getCityCode();
String url = "http://guolin.tech/api/china/" + provinceCode+"/"+citiCode;
queryFromServer(url,CURRENT_PAGE_COUNTY);
}
}
private void queryCities() {
titleTV.setText(mCurrentProvince.getProvinceName());
backBtn.setVisibility(View.VISIBLE);
// 从数据库中找
mCities = LitePal.where("provinceid=?",String.valueOf(mCurrentProvince.getId())).find(City.class);
if (mCities.size()!=0){
mListData.clear();
for (City city:mCities){
mListData.add(city.getCityName());
}
mAdapter.notifyDataSetChanged();
currentPage = CURRENT_PAGE_CITY;
}else {
int provinceCode = mCurrentProvince.getProvinceCode();
String url = "http://guolin.tech/api/china/" + provinceCode;
queryFromServer(url,CURRENT_PAGE_CITY);
}
}
/**
* 显示进度对话框
*/
private void showProgressDialog() {
if (progressDialog == null) {
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("正在加载...");
progressDialog.setCanceledOnTouchOutside(false);
}
progressDialog.show();
}
/**
* 关闭进度对话框
*/
private void closeProgressDialog() {
if (progressDialog != null) {
progressDialog.dismiss();
}
}
}
ユーティリティ :
package com.example.okhttpdemo;
import android.text.TextUtils;
import com.example.okhttpdemo.Bean.City;
import com.example.okhttpdemo.Bean.County;
import com.example.okhttpdemo.Bean.Province;
import com.google.gson.Gson;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class Utility {
/**
* 解析和处理服务器返回的省级的数据
*/
public static boolean handleProvinceResponse(String response) {
if (!TextUtils.isEmpty(response)) {
try {
JSONArray allProvinces = new JSONArray(response);
for (int i = 0; i < allProvinces.length(); i++) {
JSONObject provinceObject = allProvinces.getJSONObject(i);
Province province = new Province();
province.setProvinceName(provinceObject.getString("name"));
province.setProvinceCode(provinceObject.getInt("id"));
province.save();
}
return true;
} catch (JSONException e) {
e.printStackTrace();
}
}
return false;
}
/**
* 解析和处理服务器返回的市级的数据
*/
public static boolean handleCitiesResponse(String response,int provinceId){
if (!TextUtils.isEmpty(response)){
try {
JSONArray allCities = new JSONArray(response);
for (int i = 0; i < allCities.length() ; i++) {
JSONObject cityObject = allCities.getJSONObject(i);
City city = new City();
city.setCityName(cityObject.getString("name"));
city.setCityCode(cityObject.getInt("id"));
city.setProvinceId(provinceId);
city.save();
}
return true;
} catch (JSONException e) {
e.printStackTrace();
}
}
return false;
}
/**
* 解析和处理服务器返回的县级的数据
*/
public static boolean handleCountyResponse(String response,int cityId){
if (!TextUtils.isEmpty(response)){
try {
JSONArray allCounties = new JSONArray(response);
for (int i = 0; i < allCounties.length() ; i++) {
JSONObject countryObject = allCounties.getJSONObject(i);
County country = new County();
country.setCountyName(countryObject.getString("name"));
country.setWeatherId(countryObject.getString("weather_id"));
country.setCityId(cityId);
country .save();
}
return true;
} catch (JSONException e) {
e.printStackTrace();
}
}
return false;
}
}
HTTPツール :
package com.example.okhttpdemo;
import okhttp3.OkHttpClient;
import okhttp3.Request;
public class HttpTool {
/**
*
* @param address 接口地址URL
* @param callback
*/
public static void sendOkhttpRequest(String address,okhttp3.Callback callback){
// 1、创建OkHttpClient对象
OkHttpClient client = new OkHttpClient();
// 2、创建Request对象
Request request = new Request.Builder().url(address).build();
// 3、发送异步请求
client.newCall(request).enqueue(callback);
}
}
州 :
package com.example.okhttpdemo.Bean;
import org.litepal.crud.LitePalSupport;
public class Province extends LitePalSupport {
private int id;
private String provinceName;
private int provinceCode;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getProvinceName() {
return provinceName;
}
public void setProvinceName(String provinceName) {
this.provinceName = provinceName;
}
public int getProvinceCode() {
return provinceCode;
}
public void setProvinceCode(int provinceCode) {
this.provinceCode = provinceCode;
}
}
市:
package com.example.okhttpdemo.Bean;
import org.litepal.crud.LitePalSupport;
public class City extends LitePalSupport {
private int id;
private String cityName;
private int cityCode;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public int getCityCode() {
return cityCode;
}
public void setCityCode(int cityCode) {
this.cityCode = cityCode;
}
public int getProvinceId() {
return provinceId;
}
public void setProvinceId(int provinceId) {
this.provinceId = provinceId;
}
private int provinceId;
}
郡 :
package com.example.okhttpdemo.Bean;
import org.litepal.crud.LitePalSupport;
public class County extends LitePalSupport {
private int id;
private String countyName;
private String weatherId;
private int cityId;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCountyName() {
return countyName;
}
public void setCountyName(String countyName) {
this.countyName = countyName;
}
public String getWeatherId() {
return weatherId;
}
public void setWeatherId(String weatherId) {
this.weatherId = weatherId;
}
public int getCityId() {
return cityId;
}
public void setCityId(int cityId) {
this.cityId = cityId;
}
}
アクティビティメイン:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#7283DD"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/teal_200">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/title_text"
android:layout_centerInParent="true"
android:textColor="#fff"
android:textSize="20sp"/>
<Button
android:id="@+id/back_button"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_marginLeft="10dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="@drawable/back"
/>
</RelativeLayout>
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
litepal.xml:
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value = "okhttpdemo"/>
<version value = "1"/>
<list>
<mapping class = "com.example.okhttpdemo.Bean.Province"/>
<mapping class = "com.example.okhttpdemo.Bean.City"/>
<mapping class = "com.example.okhttpdemo.Bean.County"/>
</list>
</litepal>
Androidマニフェスト:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.okhttpdemo">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:networkSecurityConfig="@xml/network_security_config"
android:name = "org.litepal.LitePalApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.NoActionBar">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
頼る:
implementation("com.squareup.okhttp3:okhttp:3.4.1")
implementation 'org.litepal.guolindev:core:3.2.3'
implementation 'com.google.code.gson:gson:2.7'