- 發送網絡請求
請求網絡數據
需要注意哪些點: 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去發送
- 異步任務處理
代碼轉化爲異步
先新建一個內部類
如果在線程裏做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);
}
}
- 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;
}
}
- 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;
}
}
- 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();
}
}
- 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;
}
}
}
- 網絡狀態與擴展
-網絡狀態處理
· 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/