1. 程式人生 > >Android使用Okhttp3報錯java.net.UnknownServiceException

Android使用Okhttp3報錯java.net.UnknownServiceException

今天使用OkHttp庫開發安卓網路程式設計這一塊。

然後,先嚐試一個簡單的獲取伺服器XML資料,然後進行解析,程式碼如下:

private void requestXml(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder()
                            .url("http://url/android/get_data.xml").build();

                    Response response = client.newCall(request).execute();
                    String responseData = response.body().string();
                    parseXml(responseData);

                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private void parseXml(String xmlData){
        try{
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            XmlPullParser xmlPullParser = factory.newPullParser();
            xmlPullParser.setInput(new StringReader(xmlData));
            int eventType = xmlPullParser.getEventType();
            String id = "";
            String name = "";
            String version = "";
            while(eventType != XmlPullParser.END_DOCUMENT){
                String nodeName = xmlPullParser.getName();
                switch (eventType){
                    //開始解析節點
                    case XmlPullParser.START_TAG:{

                        if("id".equals(nodeName)){
                            id= xmlPullParser.nextText();
                        }else if("name".equals(nodeName)){
                            name = xmlPullParser.nextText();
                        }else if("version".equals(nodeName)){
                            version = xmlPullParser.nextText();
                        }
                        break;
                    }
                    //完成解析某個節點
                    case XmlPullParser.END_TAG:{
                        if("app".equals(nodeName)){
                            Log.d(TAG, "id is"+id);
                            Log.d(TAG, "name is"+name);
                            Log.d(TAG, "version is"+version);
                        }
                        break;
                    }
                    default:
                        break;
                }

                eventType = xmlPullParser.next();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

本來以為應該很輕鬆就能成功,可是,當我開始執行的時候,OkHttp總是會報一個錯誤,如下:

W/System.err: java.net.UnknownServiceException: CLEARTEXT communication to 10.128.249.120 not permitted by network security policy

這個錯誤,我在網上查到這個主要是由於,我們的OkHttp3會預設使用密文傳輸,而我們的程式碼中使用Http協議,也就是使用明文傳輸,所以OkHttp3會主動的報錯,然後阻止執行緒的執行。所以我們現在就是要修改配置檔案,使OkHttp3允許使用明文傳輸,或者我們直接使用Https協議。

下面,我就如何允許使用明文傳輸,說明一下方法:

1:在 res 下新建一個 xml 目錄,然後建立一個名為:network_security_config.xml 檔案 ,該檔案內容如下:

<?xml version="1.0" encoding="utf-8"?>

<network-security-config>

    <base-config cleartextTrafficPermitted="true" />

</network-security-config>
然後在 AndroidManifest.xml application 標籤內應用上面的xml配置:
<application

    android:name=".App"

    android:icon="@mipmap/ic_launcher"

    android:label="@string/app_name"

    android:networkSecurityConfig="@xml/network_security_config"

    android:roundIcon="@mipmap/ic_launcher_round"

    android:theme="@style/AppTheme">
</application>

2:伺服器和本地應用都改用 https (推薦)

3:targetSdkVersion 降級回到 27