プログラミング言語なんでもできますが伝わらない問題2
もう10年ぐらい同じことで悩んでいる気がするのは、業務に差し障るようなことがないからなんですが、やっぱりバシッと説明できるようになりたい。
そんな思いから前回の記事を書いてみて、反響もあるようなないような感じでひまなので、続編を書いてみようと思いました。
アンドロイドアプリの通信最適化
これは非技術者の営業の方に説明したら、身近なものでイメージしやすいし、できそうって思われるんじゃないだろうかという提案。
1. HTTP通信の最適化
HTTP通信は、モバイルアプリで一般的に使用される通信方法です。
最適化のための方法としては、以下の点が挙げられます。
キャッシュの使用: サーバーから頻繁に取得するデータをローカルにキャッシュし、ネットワークの使用を減らす。
圧縮: サーバーとクライアント間のデータを圧縮して送受信することで、データ転送量を削減する。
バッチリクエスト: 複数のリクエストをまとめて送信することで、ネットワークオーバーヘッドを減らす。
// 依存関係にOkHttpを追加します。
// implementation 'com.squareup.okhttp3:okhttp:4.9.3'
import okhttp3.Cache
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.File
fun setupHttpClient(context: Context): OkHttpClient {
// キャッシュサイズを設定(例: 10MB)
val cacheSize = 10 * 1024 * 1024L // 10MB
val cacheDir = File(context.cacheDir, "http_cache")
val cache = Cache(cacheDir, cacheSize)
return OkHttpClient.Builder()
.cache(cache)
.addInterceptor { chain ->
var request = chain.request()
request = if (hasNetwork(context))
request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build()
else
request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24).build()
chain.proceed(request)
}
.build()
}
fun hasNetwork(context: Context): Boolean {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetwork = connectivityManager.activeNetworkInfo
return activeNetwork != null && activeNetwork.isConnected
}
fun fetchData(client: OkHttpClient, url: String): String? {
val request = Request.Builder()
.url(url)
.build()
val response: Response = client.newCall(request).execute()
return if (response.isSuccessful) {
response.body?.string()
} else {
null
}
}
setupHttpClient: OkHttpクライアントを設定し、キャッシュを設定します。ネットワーク接続がある場合はキャッシュ時間を設定し、ない場合はキャッシュされたデータを使用します。
hasNetwork: ネットワークの有無をチェックします。
fetchData: 指定したURLからデータを取得する関数です。
2. データの圧縮
データ圧縮を使用することで、送受信するデータ量を減らし、通信コストを削減できます。
一般的には、サーバー側でgzip圧縮を使用し、クライアントで自動的に解凍します。
OkHttpを使用してgzip圧縮を有効にするには、リクエストヘッダーに設定を追加します。
fun fetchCompressedData(client: OkHttpClient, url: String): String? {
val request = Request.Builder()
.url(url)
.header("Accept-Encoding", "gzip")
.build()
val response: Response = client.newCall(request).execute()
return if (response.isSuccessful) {
response.body?.string()
} else {
null
}
}
3. バッチリクエスト
複数のリクエストをまとめて1つのリクエストとして送信することで、ネットワークのオーバーヘッドを削減できます。
具体的な実装はバックエンドとクライアントの設計に依存しますが、バッチリクエストを送ることで通信回数を減らすことができます。
// バッチリクエストのためのJSONオブジェクトを作成
val batchRequestBody = """
{
"requests": [
{ "url": "https://api.example.com/data1" },
{ "url": "https://api.example.com/data2" },
{ "url": "https://api.example.com/data3" }
]
}
"""
// バッチリクエストを送信
fun sendBatchRequest(client: OkHttpClient, url: String, batchRequestBody: String): String? {
val requestBody = batchRequestBody.toRequestBody("application/json".toMediaTypeOrNull())
val request = Request.Builder()
.url(url)
.post(requestBody)
.build()
val response: Response = client.newCall(request).execute()
return if (response.isSuccessful) {
response.body?.string()
} else {
null
}
}
4. 非同期処理とリトライ
通信の失敗時にリトライを行い、ユーザーに不便を感じさせないための非同期処理が重要です。
fun fetchDataAsync(client: OkHttpClient, url: String, retries: Int = 3, callback: (String?) -> Unit) {
val request = Request.Builder()
.url(url)
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
if (retries > 0) {
fetchDataAsync(client, url, retries - 1, callback) // リトライ
} else {
callback(null) // 失敗
}
}
override fun onResponse(call: Call, response: Response) {
if (response.isSuccessful) {
callback(response.body?.string())
} else {
callback(null)
}
}
})
}
非同期でデータを取得し、失敗した場合はリトライを行います。
リトライ回数を設定することで、通信失敗時のユーザー体験を向上させます。
説明のしかた
完全に理解はしていないけど、こういうことをちょっと聞いたら「あーね」って感じで理解できます。
そんなことを言ったらまた疑われるので、ぐっとその言葉は言うのを我慢して、下記のように説明します。
まとめ
給料は安く良い人を使いたいというのは多くの経営者の方が思っていることだと思いますが、上手に説明をして認めてもらえたら、それはお互いに価値のあることだと思います。
口下手な技術者の方も多いと思いますが、上手な自分の売り込み方や交渉力だけじゃなく技術もチームワークもコミュ力も高いレベルで身につけて、稼げる技術者になっていきたいものですね。
この記事が気に入ったらサポートをしてみませんか?