[JAVA] [Note] Concernant la communication http (okhttp3)

relier

La communication est inévitable tant que vous exécutez l'application sur votre smartphone ou tablette. Cette fois, je vais résumer la communication http. Il semble qu'il existe différentes bibliothèques, mais cette fois j'ai utilisé Okhttp3.

Importer depuis gradle

Tout d'abord, rendez Okhttp3 disponible dans l'application. Par conséquent, ajoutez-le à build.gradle (module: app). Choisissez la version que vous aimez. N'oubliez pas de synchroniser après l'ajout.

build.gradle


dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:2.0.2'
    implementation 'com.squareup.okhttp3:okhttp:4.8.0'  //← Ajouter cette ligne
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

Ajouté aux manifestes

Android ne semble pas autoriser la communication avec les applications par défaut, alors jouez avec AndroidManifests.xml. Cette fois, en plus d'INTERNET, j'ajouterai ACCESS_NETWORK_STATE, qui était nécessaire pour vérifier si le terminal est connecté au réseau.

AndroidManifests.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="sample.pack">

<!--Ajoutez les deux lignes du bas-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
    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/AppTheme"
    android:usesCleartextTraffic="true">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

Okhttp3 Lorsque l'application communique avec la dernière version d'Android, il semble qu'une erreur se produira à moins qu'elle ne soit traitée de manière asynchrone. Pour être honnête, pour les débutants, ce domaine était fou, donc la raison de la sélection était que je travaillais avec Okhttp quand je jouais avec. Je vais y mettre le produit fini pour le moment.

HttpConnector.java


package sample.pack;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

//Communication liée à l'API Web
public class HttpConnector  {
    //URL de destination
    private String urlStr  = "";
    //Chaîne de réponse
    private String respStr = "";
    //JSONArray pour la réponse
    private JSONArray respJsonArr = null;
    //Pour le traitement en veille
    private int Roop_Count;
    private int Timeout_Sec;
    private CountDownLatch countDownLatch;

    //setter et getter
    public String geturlStr(){
        return urlStr;
    }
    public void seturlStr(String urlStr){
        this.urlStr = urlStr;
    }
    //setter et getter(Prise en charge du traitement asynchrone pour la réponse)
    public String getrespStr() throws InterruptedException {
        countDownLatch.await(Timeout_Sec, TimeUnit.SECONDS);
        return respStr;
    }
    public void setrespStr(String respStr){
        countDownLatch.countDown();
        this.respStr = respStr;
    }
    public JSONArray getrespJsonArr()  throws InterruptedException {
        countDownLatch.await(Timeout_Sec, TimeUnit.SECONDS);
        return respJsonArr;
    }
    public void setrespJsonArr(JSONArray respJsonArr){
        countDownLatch.countDown();
        this.respJsonArr = respJsonArr;
    }

    //constructeur
    HttpConnector(int Roop_Count, int Timeout_Sec){
        this.Roop_Count = Roop_Count;
        this.Timeout_Sec = Timeout_Sec;
        this.countDownLatch = new CountDownLatch(Roop_Count);
    }

    //Vérifiez si le terminal est connecté au réseau
    public boolean checkConnection(Context context){
        ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkCapabilities info = cm.getNetworkCapabilities(cm.getActiveNetwork());
        return info != null;
    }

    //OBTENIR l'exécution
    public void doGet(String urlStr) {
        Request request = new Request.Builder()
                .url(urlStr)
                .get()
                .build();
        conectHttp(request);
    }

    //Exécution du POST
    public void doPost(String url, String postdata) {
        RequestBody body = RequestBody.create(postdata, MediaType.get("application/json; charset=Shift_JIS"));
        final Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        conectHttp(request);
    }

    //Envoyer une demande et recevoir une réponse
    private void conectHttp(Request request) {
        OkHttpClient client = new OkHttpClient();
        client.newCall(request).enqueue(new Callback() {
            //Lorsque la communication échoue
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
                setrespStr("");
                setrespJsonArr(null);
                Log.d("Statut","Failure");
            }
            //Si la communication réussit
            @Override
            public void onResponse(Call call, Response response) {
                try {
                    setrespStr(response.body().string());
                } catch (IOException | NullPointerException e) {
                    e.printStackTrace();
                    Log.d("Statut","Empty");
                    setrespStr("");
                }
                try {
                    setrespJsonArr(new JSONArray(respStr));
                } catch (JSONException e) {
                    e.printStackTrace();
                    Log.d("Statut","Empty");
                    setrespJsonArr(null);
                }
            }
        });
    }
}

Pour être honnête, c'est un code complètement peu convaincant, donc je suis réticent, mais avec mes capacités actuelles, c'était la limite ... Pour l'utiliser, renouvelez-le, transmettez l'URL et recevez le résultat sous forme de chaîne ou de JSONArray en tant que getter. Comme il s'agit d'un processus asynchrone, même si vous appelez getter immédiatement après avoir appelé doGet, DoPost, la valeur n'est pas définie et ne fonctionne donc pas comme prévu. J'ai donc utilisé CountDownLatch pour obtenir le getter en attente lorsque la valeur est définie dans le setter. J'essaie de définir le nombre de boucles et le délai d'expiration dans le constructeur, mais je pense que ce n'est pas très intelligent ici.

J'utilise getter en premier lieu car je n'ai pas pu renvoyer la valeur de onResponse. Je pensais que j'abandonnerais les points communs, mais cela semble être utilisé fréquemment, alors ça ressemble à ça. Au fait, le contenu de get et post est presque le même.

checkConnection () vérifie littéralement si le terminal est connecté au réseau. Nous l'utilisons pour mettre l'application en ligne / hors ligne.

Recommended Posts

[Note] Concernant la communication http (okhttp3)
[Note] Relatif à SQLite
Remarques sur la communication HTTP avec Java (OkHttp)