Androidネットワークプログラミング-OkHttpの使用

1つ、OkHttp

 

まず、公式Webサイトにアクセスして、okHttpの導入方法を確認する必要があります。 

https://square.github.io/okhttp/#releases

 図に示すように、次のコンテンツをbuild.gradleファイルに追加し、右上の同期ボタンをクリックして、okHttpの依存関係を導入しました。

implementation("com.squareup.okhttp3:okhttp:4.9.0")

 起動時にエラーが発生した場合:クラスmodule-infoにスーパータイプがありません。okhttpのバージョンを下げてください。3.5.0に減らしました。

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class Test2Activity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test2);
        init();
    }

    public void init(){
        Button btn=findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                getSync();
                getAsync();
            }
        });
    }

    //同步请求
    public void getSync(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient client=new OkHttpClient();
                Request request=new Request.Builder()
                        .get()
                        .url("你的后台地址")
                        .build();
                Call call=client.newCall(request);
                try {
                    //同步发送请求
                    Response response=call.execute();
                    if(response.isSuccessful()){
                        String s=response.body().string();
                        System.out.println("text:"+s);
                        System.out.println("请求成功");
                    }else{
                        System.out.println("请求失败");
                    }
                } catch (IOException e) {
                    System.out.println("error");
                    e.printStackTrace();
                }
            }
        }).start();
    }

    //异步请求
    public void getAsync(){
        OkHttpClient client=new OkHttpClient();
        Request request=new Request.Builder()
                .url("你的后台地址")
                .build();
        Call call=client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                System.out.println("失败");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if(response.isSuccessful()){
                    String result=response.body().string();
                    System.out.println(result);
                }
            }
        });
    }
}

 ページ上にボタンを定義し、それをクリックした後、バックグラウンドに取得リクエストを送信します

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="123"/>

</LinearLayout>

バックグラウンドデータを正常に取得する 

 

投稿リクエストを送信する

フォームを背景に投稿する

//post-表单
    public void post(){
        OkHttpClient client=new OkHttpClient();
        FormBody body=new FormBody.Builder()
                .add("test1","testValue1")
                .add("test2","testValue2")
                .add("test3","testValue3")
                .build();
        Request request=new Request.Builder()
                .url(url_post)
                .post(body)
                .build();
        Call call=client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                System.out.println("失败");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if(response.isSuccessful()){
                    String result=response.body().string();
                    System.out.println(result);
                }
            }
        });
    }

バックグラウンドでコードを受信する 

PostはJson文字列をバックグラウンドに送信します

//post-JSON字符串
    public void postJson(){
        OkHttpClient client=new OkHttpClient();
        MediaType mediaType=MediaType.parse("application/json;charset=utf-8");
        String jsonStr="{\"test1\":\"test1Value\",\"test2\":\"test2Value\",\"test3\":\"test3Value\"}";
        FormBody body= RequestBody.create();
        Request request=new Request.Builder()
                .url(url_post)
                .post(body)
                .build();
        Call call=client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                System.out.println("失败");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if(response.isSuccessful()){
                    String result=response.body().string();
                    System.out.println(result);
                }
            }
        });
    }

バックグラウンドでコードを受け取ります。ここでは、@ RequestBodyを追加してJson文字列オブジェクトを受け取ることに注意してください。 

 

 

2、改造

Retrofitの導入方法については、引き続き公式Webサイトにアクセスします:https//square.github.io/retrofit/#download

ここではバージョン2.9.0を使用しています

implementation 'com.squareup.retrofit2:retrofit:2.9.0'

 最初にインターフェースクラスを定義します

public interface ApiService {

    @GET("/test")
    Call<ResponseBody> getInfo();//无参数

    @GET("/test/{value}")
    Call<ResponseBody> getInfo4(@Path("value") String value);//路径中带参数

    @GET("/test")
    Call<ResponseBody> getInfo2(@Query("value") String value);//直接传参数

    @GET("/test")
    Call<BaseInfoModel> getInfo3(@Query("value") String value);//直接返回实体类

}

次に、Retrofitを使用して背景データをリクエストします 

public class Test3Activity extends AppCompatActivity {

    private String url="http://www.test.com/";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test3);
        init();
    }

    public void init(){
        Retrofit retrofit=new Retrofit.Builder()
                .baseUrl(url)//baseUrl必须以'/'结束
                .build();
        ApiService apiService=retrofit.create(ApiService.class);
        Call<ResponseBody> call=apiService.getInfo();
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
                if(response.isSuccessful()){
                    try {
                        String result=response.body().string();
                        System.out.println(result);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }else{
                    System.out.println("失败");
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                System.out.println(t.getMessage());
            }
        });
    }
}

毎回得られる結果は文字列であることがわかります。オブジェクトを直接取得したい場合はどうでしょうか。

まず、gsonの依存関係を紹介します

implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

次に、今すぐinitメソッドを変更します

    public void init(){
        Retrofit retrofit=new Retrofit.Builder()
                .baseUrl(url)//baseUrl必须以'/'结束
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        ApiService apiService=retrofit.create(ApiService.class);
        Call<BaseInfoModel> call=apiService.getInfo3("test");
        call.enqueue(new Callback<BaseInfoModel>() {
            @Override
            public void onResponse(Call<BaseInfoModel> call, Response<BaseInfoModel> response) {
                BaseInfoModel infoModel=response.body();
                System.out.println(infoModel);
            }

            @Override
            public void onFailure(Call<BaseInfoModel> call, Throwable t) {
                System.out.println("失败");
            }
        });
    }

 

3、RxJava

RxJava:非同期操作を実装するライブラリ

同じことが非同期で行われますが、なぜ人々は既製のAsyncTask / Handler / ...の代わりにそれを使用するのですか?プログラムロジックがますます複雑になっても、シンプルに保つことができます(https://gank.io/post/560e15be2dca930e00da1083を参照)。

たとえば、複数の画像をロードする場合:

一般的な呼び出しロジック:

new Thread() {
    @Override
    public void run() {
        super.run();
        for (File folder : folders) {
            File[] files = folder.listFiles();
            for (File file : files) {
                if (file.getName().endsWith(".png")) {
                    final Bitmap bitmap = getBitmapFromFile(file);
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            imageCollectorView.addImage(bitmap);
                        }
                    });
                }
            }
        }
    }
}.start();

 RxJavaの呼び出しロジックを使用します。

このRxJavaの実装は、ネストなしで上から下へのチェーン呼び出しであり、論理的に単純であるという利点があります。要件がより複雑になると、この利点はより明白になります(最初の10枚の写真だけを選択する必要がある場合、従来の方法で何をしますか?このような要件がさらにある場合はどうなりますか?もう一度考えてみてください。この多数の要件実装の2か月後、関数を変更する必要があります。ここに戻って、作成したパズルのインデントを確認すると、コードを再考する代わりに、すぐに理解できることが保証されます。

Observable.from(folders)
    .flatMap(new Func1<File, Observable<File>>() {
        @Override
        public Observable<File> call(File file) {
            return Observable.from(file.listFiles());
        }
    })
    .filter(new Func1<File, Boolean>() {
        @Override
        public Boolean call(File file) {
            return file.getName().endsWith(".png");
        }
    })
    .map(new Func1<File, Bitmap>() {
        @Override
        public Bitmap call(File file) {
            return getBitmapFromFile(file);
        }
    })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Action1<Bitmap>() {
        @Override
        public void call(Bitmap bitmap) {
            imageCollectorView.addImage(bitmap);
        }
    });

以下では、Rxjavaで使用しています

 implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'

ApiServiceにメソッドを追加します 

@GET("/test")
Observable<BaseInfoModel> getInfo5(@Query("cccc") String cccc);

 転送

    public void init(){
        Retrofit retrofit=new Retrofit.Builder()
                .baseUrl(url)//baseUrl必须以'/'结束
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
        ApiService apiService=retrofit.create(ApiService.class);
        apiService.getInfo5("test")
                .subscribeOn(Schedulers.io())
                .subscribe(new Observer<BaseInfoModel>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(BaseInfoModel value) {
                        System.out.println(value.toString());
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

 

おすすめ

転載: blog.csdn.net/hzkcsdnmm/article/details/112277680