网络框架OkHttp3的简单运用

         今天我们来谈谈OkHttp3这个让人遗忘的网络框架,在Volley和Retrofit的强势登场,OkHttp3相对的让人提不起兴趣。毕竟如果要使用OkHttp3就要对它进行再封装,但是这对于很多新人来说是有点困难的,他们更愿意去使用Retrofit。Anyway,我们先不谈论这三个框架的优胜劣汰,我们就单纯的讲解一下OkHttp3的简单运用。

        首先我们先创建一个OkHttp3Demo的项目,打开AS,File——New——New project,创建名为OkHttp3Demo的项目。然后打开网页OKHttp3的链接,你可以选择下载GIt项目导入但是我不建议你这么做。找到下面的这么一句代码复制单引号里面的内容:

testImplementation 'com.squareup.okhttp3:mockwebserver:3.10.0'

然后回到AS里,在创建的项目里的Model的build.gredle里面加上这么一行代码:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

    compile 'com.android.support:appcompat-v7:26.+'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    compile 'com.squareup.okhttp3:mockwebserver:3.10.0'//导入OkHttp3

}

这样我们的OkHttp3就导入到我们的项目里面了,接下来我们在activity_main.xml中加上一个按钮,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.a28062.okhttp3demo.MainActivity">

   <Button
       android:onClick="getRequest"
       android:text="GET Button"
       android:id="@+id/get_btn"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />

</LinearLayout>

        再然后我们打开MainActivity类,因为我在创建Button的时候就指定了响应方法getRequest,所以我们在这个主类中实现它的响应方法就行了。在这个方法中我们创建一个OkHttpClient的对象,这个对象我们可以把它理解为一个PC端或者一部手机,因为我们打开网页就是依靠PC或者手机的浏览器。

            我们以通过OkHttp3的GET请求百度网页为例,创建一个String类型的URL来存储链接:http://www.baidu.com 。再创建一个Request对象把URL传递进来封装好。之后调用OkHttpClient对象的newCall().enqueue()方法,把Request请求放入newCall方法中,在enqueue方法中创建一个匿名的CallBack对象,重写Callback对象中的onFailure方法和onResponse方法,当请求成功时会调用onResponse方法,反之调用onFailure方法。这是一个异步请求,当然你也可以试一下同步请求,使用newCall().execute()方法。不过耗时任务都不在主线程中执行,可能会导致程序崩溃。上代码:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void getRequest(View v){

        OkHttpClient client = new OkHttpClient();

        String URL = "http://www.baidu.com";

        Request request = new Request.Builder().url(URL).build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d("This is a test","失败:"+e.getLocalizedMessage());//当请求失败的时候我们执行onFailure方法
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.d("This is a test","成功:" +response.body().string());//当请求成功的时候我们执行onResponse方法
            }
        });


    }
}

        说完Get请求,让我们来了解一下Post请求。OkHttp3的Post请求分为表单参数形式和Json参数形式,那么最经典的案例就是关于登陆功能的实现。现在我们试着做这样一个功能,当客户填写完账号密码点击提交的时候,我们通过OkHttp3的Post请求,从控件中获取客户填写的信息发送到后端,再由后端的静态类中校验。如果账号密码都校验成功就返回一个message和一个success的状态码,然后我们再回到主线程中吐司这个message(为什么回到主线程?)。大概功能就是这样,关于接受数据的后端我相信对于聪明的你们来说应该不难我就不细说了。

        我们新建一个名为OkHttp3PostDemo的项目,打开AS选择File——new——newproject创建一个新的项目,然后导入OkHttp3依赖包,这次我们再加入一个butterknife的依赖包,在App里的Build.gradle加上下面的代码:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:26.+'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    compile 'com.jakewharton:butterknife:8.8.1'
    compile 'com.jakewharton:butterknife-compiler:8.8.1'
    compile 'com.squareup.okhttp3:mockwebserver:3.10.0'
}

        然后再在gradle里的Build.gradle加上如下代码:

    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
        classpath 'com.jakewharton:butterknife-gradle-plugin:8.8.1'
    }

        接下来我们设计一下activity_main.xml,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    android:layout_margin="5dp"
    tools:context="com.example.a28062.okhttp3postdemo.MainActivity">


    <EditText
        android:maxLines="1"
        android:hint="用户名称:"
        android:id="@+id/user_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <EditText
        android:password="true"
        android:maxLines="1"
        android:hint="用户密码:"
        android:id="@+id/pass_world"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:text="提交"
        android:id="@+id/sommint"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

        接下来我们打开MainActivity类,找到setContentView,右击里面的布局文件,选择Generate,再选择Generated ButterKnife injection,然后勾选所以的控件再在Button这个控件上勾选Onclick方法,点击确认。接下来我们在生成的Onclick方法中调用方法loginWithFrom,当然这是一个我们自己定义的方法主要是用来处理耗时任务的逻辑,我们的OkHttp3的逻辑就写在这里,传入两个参数分别为username和passworld。

           在loginWithFrom方法中我们首先创建一个okHttpClient对象,然后创建一个字符串URL用来存放要访问的地址,这里我选择了创建一个Constant的类再用里面的静态变量来存放访问地址,这样做的好处是到时可以复用并且减少代码。接下来就是Post请求中比较重要的,新建一个RequestBody对象,简单的理解为请求以什么形式提交,然后new一个RequestBody,发现New不出来。别紧张我们点进去看一下源码就回发现这个类是个抽象类所以肯定不能创建实例对象,但是它肯定有子类,我们右击抽象类选择GO TO,再选择Implementation就能看到它有两个子类。第一个FormBody字面意思,表单形式提交请求,第二个是多种形式。我们毫无疑问的选择第一个,回到主类,new一个FormBody.Builder()对象然后添加表单信息就可以了。其他的内容和Get方法一样,最重要的就是这个RequestBody的组建。上代码:

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.user_name)
    EditText userName;
    @BindView(R.id.pass_world)
    EditText passWorld;
    @BindView(R.id.sommint)
    Button sommint;
    OkHttpClient okHttpClient;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }

    @OnClick(R.id.sommint)
    public void onViewClicked() {

        String username = userName.getText().toString().trim();//获取控件内容
        String passworld = passWorld.getText().toString().trim();

        loginWithFrom(username,passworld);//调用请求方法方法

    }


    private void loginWithFrom(String username,String passworld){
        okHttpClient = new OkHttpClient();

        String URL = Constant.API.BASE_URL;//在静态类其中取出BASE_URL的访问地址
        RequestBody body = new FormBody.Builder().add("username",username).add("passworld",passworld).build();//实例化RequestBody

        final Request request =new Request.Builder()
                .post(body)//新增Post请求
                .url(URL)
                .build();

        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {


                Log.d("MainActivity","服务器开小差了");

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()){//判断服务端是否响应成功

                    String json = response.body().string();//把返回的信息存储起来

                    try {
                        JSONObject jsonObject = new JSONObject(json);//通过Json格式去获取返回的相应信息

                        String message  = jsonObject.optString("message");
                         int success  = jsonObject.optInt("success");

                        runOnUiThread(new Runnable() {//返回主线程更新UI
                            @Override
                            public void run() {
                                if (success == 1){
                                    Toast.makeText(MainActivity.this,"登陆成功",Toast.LENGTH_SHORT).show();
                                }else {
                                    Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();
                                }
                            }
                        });

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                }

            }
        });
    }

}

         接下来我们来了解一下Json参数形式的Post请求,大致上都是一样的,我们只需要改变的是RequestBody,之前我们用的是FormBody来构建表单的请求。现在我们使用Request.create()的方法来创建Json形式的请求, 还记得我们上面说的RequestBody这个抽象类的第二个子类么?我们这次就是使用它来进行提交Json形式的请求,在create里面填入MediaType.parse()方法。这个方法其实就是要我们选择一种提交形式,打开它的源码就能看见提交Json数据的格式的示范,我们填入Application/json,这样我们就选择了Json的参数形式。create方法还有个参数,我们填入我们的Json数据就可以了。        

           那么Json数据怎么存储呢?我们可以创建一个Json对象,然后使用Put方法把数据用键值对的方式一个一个的存放进去,注意这里的数据一定不能错,不然服务器会检测不了。上个代码图:

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.user_name)
    EditText userName;
    @BindView(R.id.pass_world)
    EditText passWorld;
    @BindView(R.id.sommint)
    Button sommint;
    OkHttpClient okHttpClient;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }

    @OnClick(R.id.sommint)
    public void onViewClicked() {

        String username = userName.getText().toString().trim();
        String passworld = passWorld.getText().toString().trim();

        loginWithJson(username,passworld);

    }

    private void loginWithJson(String username, String passworld) {
        okHttpClient = new OkHttpClient();

        String URL = Constant.API.BASE_URL;

        JSONObject obj = new JSONObject();//创建一个Json对象来存放数据

        try {
            
            obj.put("username",username);//使用PUT方法来存放数据
            obj.put("passworld",passworld);
            
        } catch (JSONException e) {
            e.printStackTrace();
        }

        String jsonParams = obj.toString();//将Json格式转化为字符串

        RequestBody body = RequestBody.create(MediaType.parse("Application/json"),jsonParams);//通过抽象类中的子类来构建多种形式的提交方式

        Request request =new Request.Builder()
                .post(body)
                .url(URL)
                .build();

        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {


                Log.d("MainActivity","服务器开小差了");

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()){

                    String json = response.body().string();

                    try {
                        JSONObject jsonObject = new JSONObject(json);

                        final String message  = jsonObject.optString("message");
                        final int success  = jsonObject.optInt("success");

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (success == 1){
                                    Toast.makeText(MainActivity.this,"登陆成功",Toast.LENGTH_SHORT).show();
                                }else {
                                    Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();
                                }
                            }
                        });

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                }

            }
        });
    }
}

             这样我们的OkHttp3的简单运用就讲完了,之后我可能还会写一些关于封装OkHttp3的文章,到时请大家务必过来看看,一起探讨一下哲学。手打不易哈,转载的小伙伴请标明

原创链接为:https://mp.csdn.net/postedit/80858178

GitHub地址:https://github.com/muzhilei/OkHttp3PostDemo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值