- 发送网络请求
请求网络数据
需要注意哪些点: 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/