android开发笔记之Retrofit

Retrofit 简介

A type-safe HTTP client for Android and Java

在Android网络请求库中,Retrofit是当下最热的一个网络请求库.

建议在使用前,阅读一下下面这篇文章:
Android Retrofit 2.0 的详细 使用攻略(含实例讲解)
https://www.jianshu.com/p/a3e162261ab6

Retrofit Demo: 将中文翻译成英文

实现方案:

采用Get方法对 金山词霸API 发送网络请求,采用 Gson 进行数据解析.得到数据后,在UI的TextView上显示得到的网络数据.

步骤说明:

步骤1:添加Retrofit库的依赖
步骤2:创建接收服务器返回数据的类
步骤3:创建用于描述网络请求的接口
步骤4:创建Retrofit实例
步骤5:创建网络请求接口实例并配置网络请求参数
步骤6:发送网络请求(采用最常用的异步方式)
步骤7: 处理服务器返回的数据

具体实现:

步骤1:添加Retrofit库的依赖

这里直接添加Retrofit库和converter-gson库
build.gradle

dependencies {
    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
}

添加网络权限
AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>

步骤2:创建接收服务器返回数据的类

金山词霸API 的数据格式说明如下:

// URL模板
http://fy.iciba.com/ajax.php

// URL实例
http://fy.iciba.com/ajax.php?a=fy&f=auto&t=auto&w=hello%20world

// 参数说明:
// a:固定值 fy
// f:原文内容类型,日语取 ja,中文取 zh,英语取 en,韩语取 ko,德语取 de,西班牙语取 es,法语取 fr,自动则取 auto
// t:译文内容类型,日语取 ja,中文取 zh,英语取 en,韩语取 ko,德语取 de,西班牙语取 es,法语取 fr,自动则取 auto
// w:查询内容

根据金山词霸API的数据格式,创建接收服务器返回数据的类
Translation.java

public class Translation {
    private int status;

    private content content;
    private static class content {
        private String from;
        private String to;
        private String vendor;
        private String out;
        private int errNo;
    }

    //定义输出返回数据的方法
    public String show() {
        return "status:"+status
                +" content.from:"+content.from
                +" content.to:"+content.to
                +" content.vendor:"+content.vendor
                +" content.out:"+content.out
                +" content.errNo:"+content.errNo;
    }
}

步骤3:创建用于描述网络请求的接口

采用 **注解 ** 描述 网络请求参数。
GetRequest_Interface.java

public interface GetRequest_Interface {

    @GET("ajax.php?a=fy&f=auto&t=auto&w=hello%20 one")
    Call<Translation> getCall();
    // 注解里传入 网络请求 的部分URL地址
    // Retrofit把网络请求的URL分成了两部分:一部分放在Retrofit对象里,另一部分放在网络请求接口里
    // 如果接口里的url是一个完整的网址,那么放在Retrofit对象里的URL可以忽略
    // getCall()是接受网络请求数据的方法
}

接下来的步骤均在GetRequest.java内实现(看注释)

步骤4:创建Retrofit对象
步骤5:创建 网络请求接口 的实例
步骤6:发送网络请求

public class MainActivity extends AppCompatActivity {

    private final static String TAG = "RxJavaDemo";

    private TextView textView;
    private Button button;

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

    private void init() {
        textView = (TextView) findViewById(R.id.textView);
        button =  (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.i(TAG,"button--onClick");
                onDoRetrofitDemo();
            }
        });
    }

    private void onDoRetrofitDemo() {
        //步骤4:创建Retrofit对象
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://fy.iciba.com/") // 设置 网络请求 Url
                .addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析(记得加入依赖)
                .build();

        // 步骤5:创建网络请求接口的实例
        GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);

        //对发送请求进行封装
        Call<Translation> call = request.getCall();

        //步骤6:发送网络请求(异步)
        call.enqueue(new Callback<Translation>() {
            //请求成功时回调
            @Override
            public void onResponse(Call<Translation> call, Response<Translation> response) {
                // 步骤7:处理返回的数据结果
                Log.i(TAG,response.body().show());
                textView.setText(""+response.body().show());
            }

            //请求失败时回调
            @Override
            public void onFailure(Call<Translation> call, Throwable throwable) {
                textView.setText("连接失败");
            }
        });
    }

}

运行结果:

05-09 11:14:06.722 21814-21814/com.readygo.rxjavademo I/RxJavaDemo: button--onClick
05-09 11:14:06.784 21814-21814/com.readygo.rxjavademo D/NetworkSecurityConfig: No Network Security Config specified, using platform default
05-09 11:14:07.442 21814-21814/com.readygo.rxjavademo I/RxJavaDemo: status:1 content.from:null content.to:null content.vendor:null content.out: content.errNo:0
05-09 11:14:10.949 21814-21814/com.readygo.rxjavademo I/RxJavaDemo: button--onClick
05-09 11:14:11.642 21814-21814/com.readygo.rxjavademo I/RxJavaDemo: status:1 content.from:en-EU content.to:zh-CN content.vendor:tencent content.out:你好一号 content.errNo:0

Retrofit + RxJava: 将中文翻译成英文

还是上面的例子,我们使用Retrofit + RxJava的方式来实现
绝大部分的代码一样,只需要修改部分代码.

具体实现:

步骤1:添加Retrofit库的依赖

这里直接添加Retrofit库和converter-gson库
build.gradle

dependencies {
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
    implementation 'io.reactivex.rxjava2:rxjava:2.2.8'
    
    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
    // 衔接 Retrofit & RxJava
    // 此处一定要注意使用RxJava2的版本
    implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
}

添加网络权限
AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>

步骤2:创建接收服务器返回数据的类

这一步,同上.

步骤3:创建用于描述网络请求的接口

采用 **注解 ** 描述 网络请求参数。
GetRequest_Interface.java

public interface GetRequest_Interface {

    @GET("ajax.php?a=fy&f=auto&t=auto&w=hello%20 one")
    //Call<Translation> getCall();
    Observable<Translation> getCall();
    // 注解里传入 网络请求 的部分URL地址
    // Retrofit把网络请求的URL分成了两部分:一部分放在Retrofit对象里,另一部分放在网络请求接口里
    // 如果接口里的url是一个完整的网址,那么放在Retrofit对象里的URL可以忽略
    // getCall()是接受网络请求数据的方法
}

这一步,和上面的例子有区别,区别也只是一行代码:

    Observable<Translation> getCall();

接下来的步骤均在GetRequest.java内实现(看注释)

步骤4:创建Retrofit对象
步骤5:创建 网络请求接口 的实例
步骤6:发送网络请求

public class MainActivity extends AppCompatActivity {

    private final static String TAG = "RxJavaDemo";

    private TextView textView;
    private Button button;

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

    private void init() {
        textView = (TextView) findViewById(R.id.textView);
        button =  (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.i(TAG,"button--onClick");
               onDoRetrofitRxJavaDemo();
            }
        });
    }
private void onDoRetrofitRxJavaDemo() {
        //步骤4:创建Retrofit对象
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://fy.iciba.com/") // 设置 网络请求 Url
                .addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析(记得加入依赖)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支持RxJava
                .build();

        // 步骤5:创建 网络请求接口 的实例
        GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);

        // 步骤6:采用Observable<...>形式 对 网络请求 进行封装
        Observable<Translation> observable = request.getCall();

        // 步骤7:发送网络请求
        observable.subscribeOn(Schedulers.io())               // 在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread())  // 回到主线程 处理请求结果
                .subscribe(new Observer<Translation>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }

                    @Override
                    public void onNext(Translation result) {
                        // 步骤8:对返回的数据进行处理
                        result.show();
                        Log.i(TAG,result.show());
                        textView.setText(""+result.show());
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "请求失败");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "请求成功");
                    }
                });
    }

}

运行结果:

05-09 12:21:58.991 23072-23072/com.readygo.rxjavademo I/RxJavaDemo: button--onClick
05-09 12:21:59.031 23072-23072/com.readygo.rxjavademo D/NetworkSecurityConfig: No Network Security Config specified, using platform default
05-09 12:21:59.097 23072-23072/com.readygo.rxjavademo D/RxJavaDemo: 开始采用subscribe连接
05-09 12:21:59.644 23072-23072/com.readygo.rxjavademo I/RxJavaDemo: status:1 content.from:en-EU content.to:zh-CN content.vendor:tencent content.out:你好一号 content.errNo:0
05-09 12:21:59.645 23072-23072/com.readygo.rxjavademo D/RxJavaDemo: 请求成功

其他例子

当然,Rxtrofit+ RxJava,还有许多其他例子,我们可以类比的进行学习和使用.

Android:Retrofit 结合 RxJava的优雅使用(含实例教程)
https://www.jianshu.com/p/2c54f9ccd52f

这篇文章还有5个例子,如果你有兴趣也可以阅读了:

5.1 网络请求轮询(无条件)
5.2 网路请求轮询(有条件)
5.3 网络请求嵌套回调
5.4 网络请求出错重连
5.5 合并数据源 & 统一显示

参考资料

1.github retrofit
https://github.com/square/retrofit
2.retrofit的官网
http://square.github.io/retrofit/
3.retrofit api
http://square.github.io/retrofit/2.x/retrofit/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
package com.zhy.http.okhttp; import android.os.Handler; import android.os.Looper; import android.text.TextUtils; import android.util.Log; import com.zhy.http.okhttp.cookie.SimpleCookieJar; import okhttp3.Call; import okhttp3.OkHttpClient; import okhttp3.Response; import com.zhy.http.okhttp.builder.GetBuilder; import com.zhy.http.okhttp.builder.PostFileBuilder; import com.zhy.http.okhttp.builder.PostFormBuilder; import com.zhy.http.okhttp.builder.PostStringBuilder; import com.zhy.http.okhttp.callback.Callback; import com.zhy.http.okhttp.https.HttpsUtils; import com.zhy.http.okhttp.request.RequestCall; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.TimeUnit; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; /** * Created by zhy on 15/8/17. */ public class OkHttpUtils { public static final String TAG = "OkHttpUtils"; public static final long DEFAULT_MILLISECONDS = 10000; private static OkHttpUtils mInstance; private OkHttpClient mOkHttpClient; private Handler mDelivery; private OkHttpUtils() { OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder(); //cookie enabled okHttpClientBuilder.cookieJar(new SimpleCookieJar()); mDelivery = new Handler(Looper.getMainLooper()); if (true) { okHttpClientBuilder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); } mOkHttpClient = okHttpClientBuilder.build(); } private boolean debug; private String tag; public OkHttpUtils debug(String tag) { debug = true; this.tag = tag; return this; } public static OkHttpUtils getInstance() { if (mInstance == null) { synchronized (OkHttpUtils.class) { if (mInstance == null) { mInstance = new OkHttpUtils(); } } } return mInstance; } public Handler getDelivery() { return mDelivery; } public OkHttpClient getOkHttpClient() { return mOkHttpClient; } public static GetBuilder get() { return new GetBuilder(); } public static PostStringBuilder postString() { return new PostStringBuilder(); } public static PostFileBuilder postFile() { return new PostFileBuilder(); } public static PostFormBuilder post() { return new PostFormBuilder(); } public void execute(final RequestCall requestCall, Callback callback) { if (debug) { if(TextUtils.isEmpty(tag)) { tag = TAG; } Log.d(tag, "{method:" + requestCall.getRequest().method() + ", detail:" + requestCall.getOkHttpRequest().toString() + "}"); } if (callback == null) callback = Callback.CALLBACK_DEFAULT; final Callback finalCallback = callback; requestCall.getCall().enqueue(new okhttp3.Callback() { @Override public void onFailure(Call call, final IOException e) { sendFailResultCallback(call, e, finalCallback); } @Override public void onResponse(final Call call, final Response response) { if (response.code() >= 400 && response.code() <= 599) { try { sendFailResultCallback(call, new RuntimeException(response.body().string()), finalCallback); } catch (IOException e) { e.printStackTrace(); } return; } try { Object o = finalCallback.parseNetworkResponse(response); sendSuccessResultCallback(o, finalCallback); } catch (Exception e) { sendFailResultCallback(call, e, finalCallback); } } }); } public void sendFailResultCallback(final Call call, final Exception e, final Callback callback) { if (callback == null) return; mDelivery.post(new Runnable() { @Override public void run() { callback.onError(call, e); callback.onAfter(); } }); } public void sendSuccessResultCallback(final Object object, final Callback callback) { if (callback == null) return; mDelivery.post(new Runnable() { @Override public void run() { callback.onResponse(object); callback.onAfter(); } }); } public void cancelTag(Object tag) { for (Call call : mOkHttpClient.dispatcher().queuedCalls()) { if (tag.equals(call.request().tag())) { call.cancel(); } } for (Call call : mOkHttpClient.dispatcher().runningCalls()) { if (tag.equals(call.request().tag())) { call.cancel(); } } } public void setCertificates(InputStream... certificates) { mOkHttpClient = getOkHttpClient().newBuilder() .sslSocketFactory(HttpsUtils.getSslSocketFactory(certificates, null, null)) .build(); } public void setConnectTimeout(int timeout, TimeUnit units) { mOkHttpClient = getOkHttpClient().newBuilder() .connectTimeout(timeout, units) .build(); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hfreeman2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值