数年前までアプリ開発してたんですが、とある事情でやめてました。
でも作りたいアプリがあったので、最近になって再開してます。
ただ辞めている間にAndroid Studio が出るは、いつのまにか Android がお菓子のコード名をやめたとか、次はAndroid10になるだとか・・・いろいろ状況が変わりすぎて浦島太郎状態
そこで新規一転、Android開発で学んだことをメモしてきます。
(このブログらしくWeb開発と関係のあること中心)
今回は Android でPOST送信してレスポンスを受け取る方法 について
非同期処理はメインスレッドに書いてはいけないので、
AsyncTask を使って非同期通信しないとダメになったみたいです。
このページの目次
Android6.0以降だと AsycnTask が必須みたい
AsyncTaskは文字通り非同期なタスクを実行するためのもの
POST送信とか通信系の処理は、Android6.0以降だと必ずこれを使わないとダメみたいです。
昔はUIスレッド上でも行けた気がするけど、大分状況が変わってますね。
▼ ちなみに AsyncTask の公式リファレンスでの説明
AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
引用元 : https://developer.android.com/reference/android/os/AsyncTask
▼ 上の説明の超意訳
AsyncTaskを使うと、UIスレッドを安全&簡単に使用できる。つまり、面倒なスレッドやハンドラーの操作しないでUIスレッドに結果を反映できるし、バックグラウンド操作も実行できるってこと。
この AsyncTask を使うことで、安全にPOST送信できます。
自分がよく試すのは、次で紹介する手順 です。
手順1.まずPOST送信用のデータクラスを作成
まずPOST送信しやすくするための準備から
それがPOST送信のURL・データを一括管理できるクラスの作成
別になくてもいいけど、コードを再利用しやすくなります。
ここでは SendPostTaskParams という名前で作成してみました。
▼ 実際に作ってみたクラスコード例がコチラ
1 2 3 4 5 6 7 8 9 |
class SendPostTaskParams { String url; Map<String, Object> postData; public void MyTaskParams(String url, LinkedHashMap<String, Object> postData) { this.url = url; this.postData = postData; } } |
POST送信するデータは
postData で連想配列として宣言。
あとPOST通信してレスポンスを返してもらうURLを
url で定義。
その他に必要なパラメーターがあるなら、色々追加してもOK
それにしても、こうやって Java でコード書くのも久しぶりです。
大分忘れてることもあって、クラス作るだけでもしんどかった・・・笑
まあとりあえず、こういうクラスを定義しておきます。
手順2.POST送信するAsyncTaskクラスを作成する
次に肝心のAsyncTaskクラスの作成
ここでは SendPostAsyncTask というクラス名で作ってみます。
▼ そのコード例は次の通り
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
public class SendPostAsyncTask extends AsyncTask<SendPostTaskParams, String, String> { @Override protected String doInBackground(SendPostTaskParams... params) { String urlString = params[0].url; Map<String, Object> postDataParams = params[0].postData; String response = ""; try { /// POST送信するデータをバイト配列で用意 StringBuilder postData = new StringBuilder(); for (Map.Entry<String, Object> entry : postDataParams.entrySet()) { if (postData.length() != 0) postData.append('&'); postData.append(URLEncoder.encode(entry.getKey(), "UTF-8")) .append('=') .append(URLEncoder.encode(String.valueOf(entry.getValue()), "UTF-8")); } byte[] postDataBytes = postData.toString().getBytes("UTF-8"); /// URLからコネクションを開いて色々設定 URL url = new URL(urlString); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setConnectTimeout(30000); /// レスポンスを受け取る conn.getOutputStream().write(postDataBytes); int responseCode=conn.getResponseCode(); if (responseCode == HttpsURLConnection.HTTP_OK) { String line; BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream())); while ((line=br.readLine()) != null) { response += line; } } else { response = ""; } } catch (Exception e) { System.out.println(e.getMessage()); } return response; } } |
長い・・・・・・・・・・
POST送信でこれだけ長くなるなんて アプリ開発 って大変です。
それで大事なポイントだけ箇条書きすると、こんな感じ
- 必ず
doInBackgroud をオーバーライド
このメソッドは AsyncTask が実行されたときに、 onPostExecute メソッドでレスポンスを受け取るのに必要になる。
- POSTデータはバイト配列に変換する
この例だと自作データクラス SendPostTaskParams からPOSTデータのマップを取り出し、文字列化している。そのあと postData.toString().getBytes("UTF-8"); によってバイト配列に変換。
あとは説明するのが面倒なので、コメントとか見てください。
大体なにをしてるかは分かるはずです。
手順3.ActivityからPOST送信してJSONを受け取ってみる
あとは Activity 内の onStart とか onResume でPOST送信するだけ
レスポンスは AsyncTask の onPostExecute をオーバーライドすれば受け取れます。
ただ言葉だと分かりにくいので、
実際に適当なプロジェクトを作って、実際にPOST送信してみました。
▼ そのコードがコチラ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
new SendPostAsyncTask(){ @Override protected void onPostExecute(String response) { try { JSONObject respData = new JSONObject(response); } catch ( JSONException e ) { /// 解析エラー時の処理 } Log.d( TAG, "レスポンスデータ : " + respData ); } }.execute( new SendPostTaskParams( "https://example.com/path/to/script.php", new HashMap<String, Object>(){{ put( "hoge", 12345); }} ) ); |
まず AsyncTask をインスタンス化し、 execute メソッドを実行。
ここで自作データクラス SendPostTaskParams を使い、URLとPOSTデータをいろいろ渡してます。(こういう風に、データクラスを定義すると後で楽になる)
そして onPostExecute をオーバーライドすれば、レスポンスが受け取るという感じ
AndroidでPOST送信のやり方まとめ
ちょっと長くなったので、箇条書きしてまとめます。
箇条書きだとシンプルだけど、実際にコードを書いてみると大変
改めて「 Java って複雑で冗長だな~」ってことを思い出しました。
でもPOST送信できるようになったので一件落着です。ではまた($・・)/~~~