okhttputils【 Android 一個改善的okHttp封裝庫】使用(一)

版權聲明:本文爲HaiyuKing原創文章,轉載請註明出處!html

前言

本文使用的OKHttp封裝庫是張鴻洋(鴻神)寫的,由於在項目中一直使用這個庫,因此對於一些經常使用的請求方式都驗證過,因此特此整理下。java

本文主要講的是在項目中導入OkHttpUtils庫的一些操做。至於get、post、上傳單個、多個文件、下載文件、提交文件、提交json字符串請求等,在下一篇中會有單獨的介紹。android

效果圖

代碼分析

一、導入jar包git

二、在MyApplication中配置OKHttpUtilsgithub

三、在AndroidManifest.xml中添加權限並聲明自定義的MyApplicationjson

四、建立urls.xml文件,用來設置URL地址【這種方式不太好,由於urls.xml在res中,因此容易被反編譯獲取到;應該換成在接口ServerApi中聲明常量進行調用緩存

五、建立logic包,用來封裝網絡請求服務器

六、在strings.xml文件中聲明一些經常使用的提示語cookie

使用步驟

1、項目組織結構圖

注意事項:網絡

一、導入類文件後須要change包名以及從新import R文件路徑

二、Values目錄下的文件(strings.xml、dimens.xml、colors.xml等),若是項目中存在,則複製裏面的內容,不要整個覆蓋

2、導入步驟

一、將相關jar包複製到項目的libs目錄下並同步Gradle File【這個是eclipse上的用法】【Android studio中直接使用compile 'com.zhy:okhttputils:2.6.2'

jar包下載地址:連接:https://pan.baidu.com/s/1AL4zYlgydc2dJ3A9dy4vaA 密碼:4gmh

其中,gson-2.2.4.jar用於Post Json提交。【這個是必須單獨引用的,無論Android studio仍是eclipse】

同步Gradle File後:

二、建立一個包含如下代碼的MyApplication.java(自定義的Application子類)

package com.why.project.okhttputilsbasedemo;

import android.app.Application;
import android.content.Context;

import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.cookie.CookieJarImpl;
import com.zhy.http.okhttp.cookie.store.PersistentCookieStore;
import com.zhy.http.okhttp.https.HttpsUtils;
import com.zhy.http.okhttp.log.LoggerInterceptor;

import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;

import okhttp3.OkHttpClient;

/**
 * Created by HaiyuKing
 * Used 自定義Application
 */

public class MyApplication extends Application{

    /**系統上下文*/
    private static Context mAppContext;

    @Override
    public void onCreate() {
        super.onCreate();
        mAppContext = getApplicationContext(); initOkHttp();//配置OkhttpClient
    }

    /**獲取系統上下文:用於ToastUtil類*/
    public static Context getAppContext() { return mAppContext; } /** * 配置OkhttpClient */
    private void initOkHttp() { CookieJarImpl cookieJar = new CookieJarImpl(new PersistentCookieStore(getApplicationContext()));//修改爲自帶的cookie持久化,能夠解決程序崩潰時返回到 //ClearableCookieJar cookieJar1 = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(getApplicationContext()));
 HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(null, null, null);//設置可訪問全部的https網站
 OkHttpClient okHttpClient = new OkHttpClient.Builder() .connectTimeout(60000L, TimeUnit.MILLISECONDS) .readTimeout(60000L, TimeUnit.MILLISECONDS) //配置Log,經過設置攔截器實現,框架中提供了一個LoggerInterceptor,固然你能夠自行實現一個Interceptor
                .addInterceptor(new LoggerInterceptor("TAG")) //配置持久化Cookie(包含Session)
 .cookieJar(cookieJar) .hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { // TODO Auto-generated method stub
                        return false; } }) //配置Https
 .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager) .build(); OkHttpUtils.initClient(okHttpClient); }

}

三、在AndroidManifest.xml中添加權限並聲明這個MyApplication

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

    <!-- ======================受權訪問網絡(OkHttpUtil)========================== -->
    <!-- 容許程序打開網絡套接字 -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <!-- 容許程序訪問有關GSM網絡信息 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!-- 容許程序訪問Wi-Fi網絡狀態信息 -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <!-- 容許一個程序訪問精良位置(如GPS) -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!-- 訪問電話狀態 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <!-- 容許程序寫入外部存儲,如SD卡上寫文件 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!-- 容許程序讀外部存儲,如SD卡上讀文件 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    <!-- ======================受權訪問網絡(HttpUtil)========================== -->
    <!-- 容許程序打開網絡套接字 -->
    <!--<uses-permission android:name="android.permission.INTERNET"/>-->
    <!-- 容許程序訪問有關GSM網絡信息 -->
    <!--<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />-->
    <!-- 容許程序訪問Wi-Fi網絡狀態信息 -->
    <!--<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />-->
    <!-- 容許一個程序訪問精良位置(如GPS)  -->
    <!--<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />-->
    <!-- 訪問電話狀態 -->
    <!--<uses-permission android:name="android.permission.READ_PHONE_STATE" />-->

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" android:name=".MyApplication">
        <activity android:name=".activity.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

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

</manifest>

四、添加運行時權限的處理(本demo中採用的是修改targetSDKVersion=22)

五、將urls.xml文件複製到項目的res/valus目錄中【存在反編譯的風險,捨棄不用了;這裏留做記錄,後續再也不保留這個文件】

<?xml version="1.0" encoding="utf-8"?>
<!-- 全部接口的url地址 -->
<resources>
    
    <!-- 域名(開發環境) -->
    <string name="server_url">http://www.weather.com.cn/data/sk/</string>
    <!-- 域名(測試環境) -->
    <!-- <string name="server_url"></string> -->
    <!-- 域名(正式環境) -->
    <!-- <string name="server_url"></string> -->

    <!-- get請求地址 -->
    <string name="get_url">101010100.html</string>

</resources>

五、將ServerApi文件複製到項目中

package com.why.project.okhttputilsbasedemo.logic;

/**
 * Created by HaiyuKing
 * Used 接口地址
 */

public interface ServerApi {

    String SERVER_URL = "http://www.weather.com.cn/data/sk/";// 域名(開發環境)
    String GET_URL = "101010100.html";// get請求地址

}

六、將BaseLogic.java、LoginLogic.java複製到項目中

package com.why.project.okhttputilsbasedemo.logic;

import android.content.Context;

import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.cookie.CookieJarImpl;
import com.zhy.http.okhttp.cookie.store.CookieStore;

import java.util.List;

import okhttp3.Cookie;
import okhttp3.CookieJar;

public class BaseLogic {

    protected Context context;
    public final String charset = "GBK";//例如:URLEncoder.encode("中途結束", charset)
    
    /**拼接完整的URL地址*/
    protected String getSpcyUrl(String serverUrl){
        String url = ServerApi.SERVER_URL + serverUrl;
        return url;
    }

    /**獲取cookies*/
    public static String getCookiesStr(){
        String cookiesInfo = "";
        CookieJar cookieJar = OkHttpUtils.getInstance().getOkHttpClient().cookieJar();
        if (cookieJar instanceof CookieJarImpl)
        {
            CookieStore cookieStore = ((CookieJarImpl) cookieJar).getCookieStore();
            List<Cookie> cookies = cookieStore.getCookies();
            for(Cookie cookie : cookies){
                cookiesInfo = cookiesInfo + cookie.name() + ":" + cookie.value() + ";";
            }
        }

        return cookiesInfo;
    }

    /**清空cookie緩存*/
    public static void clearCookies()
    {
        CookieJar cookieJar = OkHttpUtils.getInstance().getOkHttpClient().cookieJar();
        if (cookieJar instanceof CookieJarImpl)
        {
            ((CookieJarImpl) cookieJar).getCookieStore().removeAll();
        }
    }

}
BaseLogic.java
package com.why.project.okhttputilsbasedemo.logic;

import com.why.project.okhttputilsbasedemo.MyApplication;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;


/**
 * @Created HaiyuKing
 * @Used   登陸界面相關接口
 */
public class LoginLogic extends BaseLogic {
    
    private static LoginLogic _Instance = null;

    public static LoginLogic Instance() {
        if (_Instance == null)
            _Instance = new LoginLogic();
        return _Instance;
    }
    private LoginLogic() {
        this.context = MyApplication.getAppContext();//防止了內存泄漏
    }

    /**
     * get請求測試
     */
    public String getJsonApi(StringCallback callback)
            throws Exception {
        String result = "";
        OkHttpUtils
                .get()
                .url(getSpcyUrl(ServerApi.GET_URL))
                .id(100)
                .tag(context)
                .build()
                .execute(callback);
        return result;
    }

}
LoginLogic.java

七、在strings.xml文件中添加如下代碼

<resources>
    <string name="app_name">OkHttpUtilsBaseDemo</string>

    <!-- ******************公共字段:用於OkHttpUtil****************** -->
    <string name="login_succeed">登陸成功</string>
    <string name="login_fail_username_pwd">用戶名或密碼錯誤,請檢查!</string>
    <string name="login_fail_username">用戶不存在,請聯繫管理員!</string>
    <string name="login_over_exception">用戶已到期,請聯繫管理員!</string>
    <string name="login_null_exception">服務器響應超時,請稍後重試!</string>
    <string name="login_json_exception">服務器數據解析異常,請聯繫管理員!</string>
    <string name="login_again">用戶超時,請從新登陸!</string>

    <string name="response_null">數據內容爲空</string>
    <string name="response_fail">請求失敗,請從新請求!</string>

    <!-- ******************公共字段:用於HttpUtil****************** -->
    <string name="network_enable">當前網絡未鏈接</string>
    <string name="network_terrible">當前網絡不佳,請檢查您的網絡設置。</string>
    <string name="network_error">網絡鏈接異常</string>
    <string name="network_timeout">網絡請求超時,請重試</string>
    <string name="network_unavailable">網絡鏈接不可用</string>
    <!-- 公共字段 end-->

</resources>

3、使用方法

通常搭配HttpUtil、ToastUtil工具類使用。

注意:Toast提示,這裏使用的是ToastUtil【簡單的Toast封裝類】【未自定義Toast的顯示風格】

package com.why.project.okhttputilsbasedemo.activity;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.why.project.okhttputilsbasedemo.MyApplication;
import com.why.project.okhttputilsbasedemo.R;
import com.why.project.okhttputilsbasedemo.logic.LoginLogic;
import com.why.project.okhttputilsbasedemo.utils.ToastUtil;
import com.why.project.okhttputilsbasedemo.utils.httputil.HttpUtil;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;

import org.json.JSONException;
import org.json.JSONObject;

import okhttp3.Call;
import okhttp3.Request;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    private Button btn_get;
    private TextView tv_show;

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

        initViews();
        initEvents();
    }

    @Override
    public void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        //取消網絡請求,根據tag取消請求
        OkHttpUtils.getInstance().cancelTag(this);
    }

    private void initViews() {
        btn_get = (Button) findViewById(R.id.btn_get);
        tv_show = (TextView) findViewById(R.id.tv_show);
    }

    private void initEvents() {
        btn_get.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getJson();
            }
        });
    }

    private void getJson() {
        if (HttpUtil.isNetworkAvailable(this)) { //執行網絡請求接口
            try { LoginLogic.Instance().getJsonApi(new GetJsonStringCallback()); } catch (Exception e) { e.printStackTrace(); } }else{ ToastUtil.showShortToast(MyApplication.getAppContext().getResources().getString(R.string.network_enable)); }
    }

    /** * get接口的自定義回調函數*/
    public class GetJsonStringCallback extends StringCallback { @Override public void onBefore(Request request, int id) {//showProgressDialog("");//顯示進度加載框
 } @Override public void onAfter(int id) {//dismissProgressDialog();//隱藏進度加載框
 } @Override public void onError(Call call, Exception e, int id) { ToastUtil.showShortToast(MyApplication.getAppContext().getResources().getString(R.string.login_again)); Log.w(TAG,"{onError}e="+e.toString()); } @Override public void onResponse(String response, int id) { Log.e(TAG, "onResponse:response="+response); switch (id) { case 100://http
                    try { if (response != null && !"".equals(response)){ //解析
                            JSONObject responseObj = new JSONObject(response); tv_show.setText(responseObj.toString()); } else { ToastUtil.showShortToast(MyApplication.getAppContext().getResources().getString(R.string.login_null_exception)); } } catch (JSONException e) { ToastUtil.showShortToast(MyApplication.getAppContext().getResources().getString(R.string.login_json_exception)); }catch (Exception e) { ToastUtil.showShortToast(MyApplication.getAppContext().getResources().getString(R.string.login_json_exception)); } finally { } break; case 101://https
                    break; } } @Override public void inProgress(float progress, long total, int id) { Log.e(TAG, "inProgress:" + progress); } }
}

混淆配置

#=====================okhttputils框架=====================
#====okhttputils====
#android Studio環境中不須要,eclipse環境中須要
#-libraryjars libs/okhttputils.jar
-dontwarn com.zhy.http.**
-keep class com.zhy.http.**{*;}
-keep interface com.zhy.http.**{*;}

#====okhttp====
#android Studio環境中不須要,eclipse環境中須要
#-libraryjars libs/okhttp-2.7.0.jar
-dontwarn okhttp3.**
-keep class okhttp3.**{*;}
-keep interface okhttp3.**{*;}

-keepattributes Signature
-keepattributes *Annotation*
-dontwarn com.squareup.okhttp.**
-keep class com.squareup.okhttp.**{*;}
-keep interface com.squareup.okhttp.**{*;}

#====okio====
#android Studio環境中不須要,eclipse環境中須要
#-libraryjars libs/okio-1.6.0.jar
-dontwarn java.nio.file.*
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-dontwarn okio.**
-keep class okio.**{*;}
-keep interface okio.**{*;}

#====gson====
#android Studio環境中不須要,eclipse環境中須要
#-libraryjars libs/gson-2.2.4.jar
-keep class sun.misc.Unsafe{*;}
-dontwarn com.google.gson.**
-keep class com.google.gson.**{*;}
-keep class com.google.gson.stream.**{*;}
#這一段包名應該是你全部的java bean 定義的目錄
-keep class com.google.gson.examples.android.model.**{*;}

須要注意,在Android studio開發環境和eclipse開發環境中,混淆配置不一樣之處在於下面的註釋標註的:

#android Studio環境中不須要,eclipse環境中須要
#-libraryjars libs/okhttputils.jar

參考資料

Android 一個改善的okHttp封裝庫

github地址

項目demo下載地址

https://github.com/haiyuKing/OkHttpUtilsBaseDemo

相關文章
相關標籤/搜索