筆記-7 網絡編程數據處理

  1. 發送網絡請求
    請求網絡數據
    需要注意哪些點: 1. 需要有網絡權限;2. 異步
    如何下載電影,音樂,遊戲等//本質還是網絡請求

First we create an Network Activity, extends Activity, add a button on MainActivity which can be clicked and jump to NetworkActivity
in activity_network.xml:

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

    <!--頁面的目的
    1. EditText顯示一串網址
    2. Button裏面來獲取數據
    3. 在Text裏面展示出來頁面-->

    <EditText
        android:id="@+id/edit_Text"
        android:layout_gravity="center_horizontal"
        android:layout_width="match_parent"
        android:hint="Please enter the URL "
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:text="Get Data"
        android:layout_gravity="center_horizontal"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/textView"
        android:text="Webpage content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>
public class NetworkActivity extends Activity implements View.OnClickListener {

    private EditText mEditText;
    private TextView mTextView;
    private Button mButton;

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

        findViews(); 
        setListeners();


    }

    private void setListeners() {
        mButton.setOnClickListener(this);
    }

    private void findViews() {
        mEditText = (EditText) findViewById(R.id.editText);
        mTextView = (TextView) findViewById(R.id.textView); 
        mButton = (Button) findViewById(R.id.button); 
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button:
                String url = getEditTextUrl(); //get the URL

                // 請求網絡數據 - 去Manifest裏申請一下,去吧~
                String data = requestData(url);
                mTextView.setText(data);
                requestData(url);
                break;
        }
    }

    private String getEditTextUrl() {

        return mEditText != null ? mEditText.getText().toString() :""; // 保證editText不會變空指針
    }


    private String requestData(String urlString) { //會出現exception,加一下try/catch就好
        try {
            URL url = new URL(urlString); //是將一個網絡請求封裝成一個URL類
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(15000); //超時
            connection.setRequestMethod("GET"); //GET, POST, DELETE, PUT, HEAD, TRACE etc...*check PERMITTED_USER_METHODS

            connection.connect();
            int responseCode = connection.getResponseCode();
            String responseMessage = connection.getResponseMessage();

            InputStream inputStream = connection.getInputStream();
            Reader reader = new InputStreamReader(inputStream, "UTF-8");
            char[] buffer = new char[1024];
            reader.read(buffer);
            String content = new String(buffer); //內容就讀出來啦
            return content;

        } catch (MalformedURLException e) {
            e.printStackTrace(); // 輸入非法的URL會拋出異常
            Toast.makeText(NetworkActivity.this,"URL illegal",Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(NetworkActivity.this,"R/W Exception",Toast.LENGTH_SHORT).show();

        }
        return null;
    }
}

注意:要在Manifest裏面申請網絡權限
所有的網絡請求要異步操作-可以用線程去做,然後用Handler去發送

  1. 異步任務處理

代碼轉化爲異步
先新建一個內部類

如果在線程裏做UI的事情,會閃退
//異步任務處理

 class RequestNetworkDataTask extends AsyncTask<String,Integer, String>{                   

     //在後臺處理前                                                                              
     @Override                                                                             
     protected void onPreExecute() {                                                       
         super.onPreExecute();                                                             
         //在主線程                                                                            
         //加載數據   UI Loading                                                               
     }                                                                                     

     @Override                                                                             
     protected String doInBackground(String[] params) {                                    

         String result = requestData(params[0]);                                           
         return result;                                                                    
     }                                                                                     

     @Override                                                                             
     protected void onPostExecute(String result) {                                         
         super.onPostExecute(result);                                                      
         //執行完後在主線程中                                                                       
         mTextView.setText(result);                                                        

     }                                                                                     

     @Override                                                                             
     protected void onCancelled() {                                                        
         super.onCancelled();                                                              
     }                                                                                     

     @Override                                                                             
     protected void onProgressUpdate(Integer... values) {                                  
         super.onProgressUpdate(values);                                                   
     }                                                                                     
 }                       
  1. XML之SAX解析

新建tesSAXParse(); SAXParseHandler類,繼承DefaultHandler
實現其startDocument(); endDocument(); startElement(); endElement(); characters();

public class SAXParseHandler extends DefaultHandler {

    List<WebURL> mWebURLs;
    WebURL mWebURL;

    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        mWebURLs = new ArrayList<>();
    }

    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        mWebURL = new WebURL();
        if (TextUtils.equals(localName,"item"));
        for (int i = 0; i <attributes.getLength() ; i++) {
            if (TextUtils.equals(attributes.getLocalName(i),"id")){
                mWebURL.setmID(Integer.valueOf(attributes.getValue(i)));
            }
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        String content = String.valueOf(ch,start,length);
    }

    public List<WebURL> getXMLList() {
        return mWebURLs;
    }
}
public class SAXParseHandler extends DefaultHandler {

    List<WebURL> mWebURLs;
    WebURL mWebURL;

    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        mWebURLs = new ArrayList<>();
    }

    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        mWebURL = new WebURL();
        if (TextUtils.equals(localName,"item"));
        for (int i = 0; i <attributes.getLength() ; i++) {
            if (TextUtils.equals(attributes.getLocalName(i),"id")){
                mWebURL.setmID(Integer.valueOf(attributes.getValue(i)));
            }
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        String content = String.valueOf(ch,start,length);
    }

    public List<WebURL> getXMLList() {
        return mWebURLs;
    }
}
  1. XML之Pull Dom解析
// pull 解析只有xml裏面才能得到
        XmlResourceParser xmlResourceParser = getResources().getXml(R.xml.test);

        try {
            while (xmlResourceParser.getEventType() != XmlResourceParser.END_DOCUMENT){

                if(xmlResourceParser.getEventType()== XmlResourceParser.START_TAG){
                    String tagName = xmlResourceParser.getName();
                    if(TextUtils.equals(tagName, "item")){
                        String id = xmlResourceParser.getAttributeValue(null, "id");
                    }
                }
            }
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }

        //DOM - read whole file - small files

    }


    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.network_button:
                startActivity(new Intent(MainActivity.this,NetworkActivity.class));
                break;
        }
    }
  1. JSON解析
    較之XML, JSON更輕量級,空間小,下載更快,同時和JS的交互更方便
    JSONObject
    android.jar - org - json - JSONObject/JSONArray/JSONException/JSONStringer/JSONTokener

json簡單說就是javascript中的對象和數組,所以這兩種結構就是對象和數組兩種結構,通過這兩種結構可以表示各種複雜的結構。

JSONStringer: 幫助生成一些格式

 //JSON 的解析
        InputStream is = getResources().openRawResource(R.raw.json);
        String jsonString = getStringbyInputStream(is);

        try {
            JSONObject jsonObject = new JSONObject(jsonString);
            String title = jsonObject.getString("title");
            JSONObject userJSONObject = jsonObject.getJSONObject("user");
            userJSONObject.getLong("id");
            JSONArray jsonArray = jsonObject.getJSONArray("images");
            jsonArray.get(0);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
  1. JSON之GSON解析
public class UserData {

    @SerializedName("title")
    private String mTitle; 

    @SerializedName("content")
    private String mContent; 

    @SerializedName("user")
    private String mUser; 


    @SerializedName("images")
    private List<String> mImages;

    public String getmTitle() {
        return mTitle;
    }

    public void setmTitle(String mTitle) {
        this.mTitle = mTitle;
    }

    public String getmContent() {
        return mContent;
    }

    public void setmContent(String mContent) {
        this.mContent = mContent;
    }

    public String getmUser() {
        return mUser;
    }

    public void setmUser(String mUser) {
        this.mUser = mUser;
    }

    public List<String> getmImages() {
        return mImages;
    }

    public void setmImages(List<String> mImages) {
        this.mImages = mImages;
    }

    public class User{

        @SerializedName("id")
        private String mID;

        @SerializedName("name")
        private String mName;

        @SerializedName("avatar")
        private String mAvatar;

        public String getmID() {
            return mID;
        }

        public void setmID(String mID) {
            this.mID = mID;
        }

        public String getmName() {
            return mName;
        }

        public void setmName(String mName) {
            this.mName = mName;
        }

        public String getmAvatar() {
            return mAvatar;
        }

        public void setmAvatar(String mAvatar) {
            this.mAvatar = mAvatar;
        }
    }
}
  1. 網絡狀態與擴展

-網絡狀態處理
· ConnectivityManager
· NetworkInfo // already deprecated, can use **instead (tbd)

public class NetworkUtil {

    public void testNetwork(Context context){
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); //關於網絡連接的查詢結果
        NetworkInfo networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        boolean isWifiConnection = networkInfo.isConnected();
        networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); //移動網絡
        boolean isMobileConnection = networkInfo.isConnected(); 
    }


    public boolean isOnline(){
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        return (networkInfo != null && networkInfo.isConnected());

    }
}

新建一個網絡工具類NetworkUtil

-常用網絡開源庫 //GitHub
· android-async-http
·Volley
·OKHttp
·Retrofit

-完善
·封裝請求及通用設置-封裝能用Header-請求參數封裝
·封裝結果處理-能用錯誤碼處理-數據轉換及校驗
-攔截請求設置及代理 //抓包
·Fiddler (Windows)
·Charles(Mac)
·WiFi設置代理

Tips:
- Postman 查詢API
- 瞭解Restful API

補充鏈接:
AS裏的快捷鍵:http://ask.android-studio.org/?/article/12
About JSON: http://www.json.cn/
百科:http://baike.baidu.com/link?url=gVXOnhLzZJlo2IePCEwhmGBKj4Ku9-duNJWjrPtLAZ9W4N9whR9B7VWZDwf_5hCRsn8oeI1_4RYXLARaoNAiXq
JSON格式化工具網站:http://jsonlint.com/

發佈了38 篇原創文章 · 獲贊 9 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章