編輯:關於Android編程
一般網絡數據通過http來get,post,那麼其中的數據不可能雜亂無章,比如我要post一段數據,肯定是要有一定的格式,協議的。常用的就是xml和json了。在此先要搭建個簡單的服務器吧,首先呢下載xampp,然後安裝之類的就不再多講了。安裝好後,啟動xampp,之後在浏覽器輸入localhost或者127.0.0.1就可以看到如下所示了:

這個就表示服務器已經運行了,具體的代碼都是放在這個/Applications/XAMPP/htdocs目錄下的。然後待會兒編寫個xml文件也放在這裡。 編寫個簡單的xml文件吧。
2
3
4 25
5
6
7
8
9
10 15
11
12
13
14
這裡為了方便,我在htdocs下面新建了一個test文件夾,然後再新建了一個person.xml文件,習慣了用vim,這裡就用vim來實現了一把,保存退出後,我們去看下效果,打開chrome浏覽器,輸入http://localhost/test/person.xml。發現浏覽器如下圖所示:
顯示的內容就是我們文件的內容,接下去通過app去獲取這個信息。
xml解析主要有三種方式,SAX,Pull,Dom。下面就用這幾種方法來實現下。
首先是SAX方式,SAX方式主要是兩部分組成,一部分是解析器,也就是XMLReader接口,負責讀取XML文檔,另一部分是事件處理器ContentHandler,負責對發送事件響應和進行XML文檔處理。
繼承DefaultHandler,並重寫5個父類的方法。
1、startDocument方法:開始XML解析的時候調用。
2、startElement方法:開始解析某個節點的時候調用。
3、characters方法:獲取節點內容的時候調用。
4、endElement方法:解析完某個節點的時候調用。
5、endDocument方法:完成XML解析時候調用。
先新建類SAXContentHandler類,繼承DefaultHandler類,編寫代碼如下:
package com.jared.emxmlstudy;
import android.util.Log;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* Created by jared on 16/2/19.
*/
public class SAXContentHandler extends DefaultHandler {
private static final String TAB = "SAXContentHandler";
private String nodeName;
private StringBuffer mName;
private StringBuffer mAge;
private StringBuffer mSex;
private StringBuffer mClass;
@Override
public void startDocument() throws SAXException {
mName = new StringBuffer();
mAge = new StringBuffer();
mSex = new StringBuffer();
mClass = new StringBuffer();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
nodeName = localName;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if("name".equals(nodeName)) {
mName.append(ch, start, length);
}else if("age".equals(nodeName)) {
mAge.append(ch, start, length);
} else if("sex".equals(nodeName)) {
mSex.append(ch, start, length);
} else if("class".equals(nodeName)) {
mClass.append(ch, start, length);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if("Teacher".equals(localName)) {
Log.d(TAB, "This is Teacher");
Log.d(TAB, "name is:" + mName.toString().trim());
Log.d(TAB, "age is:" + mAge.toString().trim());
Log.d(TAB, "sex is:" + mSex.toString().trim());
Log.d(TAB, "class is:" + mClass.toString().trim());
mName.setLength(0);
mAge.setLength(0);
mSex.setLength(0);
mClass.setLength(0);
} else if("Student".equals(localName)) {
Log.d(TAB, "This is Student");
Log.d(TAB, "name is:" + mName.toString().trim());
Log.d(TAB, "age is:" + mAge.toString().trim());
Log.d(TAB, "sex is:" + mSex.toString().trim());
mName.setLength(0);
mAge.setLength(0);
mSex.setLength(0);
}
}
@Override
public void endDocument() throws SAXException {
}
}
這裡要使用三種方法,所以修改布局如下:
<!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%2D%2D%3E-->
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:layout_margin="10dp" tools:context="com.jared.emxmlstudy.MainActivity"><button android:id="@+id/getXmlsax" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="SAX方式獲取"></button><button android:id="@+id/getXmlpull" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Pull方式獲取"></button><button android:id="@+id/getXmldom" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Dom方式獲取"></button></linearlayout>
然後MainActivity中添加代碼如下;
package com.jared.emxmlstudy;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import java.io.StringReader;
import javax.xml.parsers.SAXParserFactory;
import cz.msebera.android.httpclient.Header;
public class MainActivity extends AppCompatActivity {
private static final String xmlUrl = "http://192.168.1.102/test/person.xml";
private Button mGetXmlSax;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGetXmlSax = (Button)findViewById(R.id.getXmlsax);
mGetXmlSax.setOnClickListener(new myOnClickListener());
}
private class myOnClickListener implements View.OnClickListener {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.getXmlsax:
sendRequestWithAsyncHttpClient(xmlUrl);
break;
default:
break;
}
}
}
private void sendRequestWithAsyncHttpClient(String url) {
AsyncHttpClient client = new AsyncHttpClient();
client.get(url, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int i, Header[] headers, byte[] bytes) {
try {
String response = new String(bytes, 0, bytes.length, "utf-8");
parseXMLWithSax(response);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
}
});
}
private void parseXMLWithSax(String xmlData) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader xmlReader = factory.newSAXParser().getXMLReader();
SAXContentHandler mHandler = new SAXContentHandler();
xmlReader.setContentHandler(mHandler);
xmlReader.parse(new InputSource(new StringReader(xmlData)));
} catch (Exception e) {
e.printStackTrace();
}
}
}
實例化一個factory,通過XMLReader來讀取解析。運行點擊按鈕如下顯示:
02-19 21:01:58.661 17390-17390/? D/SAXContentHandler: This is Teacher 02-19 21:01:58.661 17390-17390/? D/SAXContentHandler: name is:xiao hong 02-19 21:01:58.661 17390-17390/? D/SAXContentHandler: age is:25 02-19 21:01:58.661 17390-17390/? D/SAXContentHandler: sex is:woman 02-19 21:01:58.661 17390-17390/? D/SAXContentHandler: class is:english 02-19 21:01:58.661 17390-17390/? D/SAXContentHandler: This is Student 02-19 21:01:58.661 17390-17390/? D/SAXContentHandler: name is:xiao ming 02-19 21:01:58.661 17390-17390/? D/SAXContentHandler: age is:15 02-19 21:01:58.661 17390-17390/? D/SAXContentHandler: sex is:man可以發現已經得到我們想要的信息了。
接著使用Pull方式,開始解析可以通過調用它的next方法,獲取下一個事件,可以通過getAttribute方法獲取屬性,通過nextText方法來獲取節點的值。編寫代碼如下:
package com.jared.emxmlstudy;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.StringReader;
import javax.xml.parsers.SAXParserFactory;
import cz.msebera.android.httpclient.Header;
public class MainActivity extends AppCompatActivity {
private static final String TAB = "XMLParse";
private static final String xmlUrl = "http://192.168.1.102/test/person.xml";
private Button mGetXmlSax;
private Button mGetXmlPull;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGetXmlSax = (Button)findViewById(R.id.getXmlsax);
mGetXmlPull = (Button)findViewById(R.id.getXmlpull);
mGetXmlSax.setOnClickListener(new myOnClickListener());
mGetXmlPull.setOnClickListener(new myOnClickListener());
}
private class myOnClickListener implements View.OnClickListener {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.getXmlsax:
sendRequestWithSax(xmlUrl);
break;
case R.id.getXmlpull:
sendRequestWithPull(xmlUrl);
break;
default:
break;
}
}
}
private void sendRequestWithPull(String url) {
AsyncHttpClient client = new AsyncHttpClient();
client.get(url, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int i, Header[] headers, byte[] bytes) {
try {
String response = new String(bytes, 0, bytes.length, "utf-8");
parseXMLWithPull(response);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
}
});
}
private void parseXMLWithPull(String xmlData) {
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
xmlPullParser.setInput(new StringReader(xmlData));
int eventType = xmlPullParser.getEventType();
String mName = "";
String mAge = "";
String mSex = "";
String mClass = "";
while (eventType != XmlPullParser.END_DOCUMENT) {
String nodeName = xmlPullParser.getName();
switch (eventType) {
case XmlPullParser.START_TAG: {
if("name".equals(nodeName)) {
mName = xmlPullParser.nextText();
} else if("age".equals(nodeName)) {
mAge = xmlPullParser.nextText();
} else if("sex".equals(nodeName)) {
mSex = xmlPullParser.nextText();
} else if("class".equals(nodeName)) {
mClass = xmlPullParser.nextText();
}
break;
}
case XmlPullParser.END_TAG: {
if("Teacher".equals(nodeName)) {
Log.d(TAB, "This is Teacher");
Log.d(TAB, "name is:" + mName.trim());
Log.d(TAB, "age is:" + mAge.trim());
Log.d(TAB, "sex is:" + mSex.trim());
Log.d(TAB, "class is:" + mClass.trim());
} else if("Student".equals(nodeName)) {
Log.d(TAB, "This is Student");
Log.d(TAB, "name is:" + mName.trim());
Log.d(TAB, "age is:" + mAge.trim());
Log.d(TAB, "sex is:" + mSex.trim());
}
}
default:
break;
}
eventType = xmlPullParser.next();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void sendRequestWithSax(String url) {
AsyncHttpClient client = new AsyncHttpClient();
client.get(url, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int i, Header[] headers, byte[] bytes) {
try {
String response = new String(bytes, 0, bytes.length, "utf-8");
parseXMLWithSax(response);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
}
});
}
private void parseXMLWithSax(String xmlData) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader xmlReader = factory.newSAXParser().getXMLReader();
SAXContentHandler mHandler = new SAXContentHandler();
xmlReader.setContentHandler(mHandler);
xmlReader.parse(new InputSource(new StringReader(xmlData)));
} catch (Exception e) {
e.printStackTrace();
}
}
}
運行結果如下:
02-19 21:52:01.391 19388-19388/? D/XMLParse: This is Teacher 02-19 21:52:01.391 19388-19388/? D/XMLParse: name is:xiao hong 02-19 21:52:01.391 19388-19388/? D/XMLParse: age is:25 02-19 21:52:01.391 19388-19388/? D/XMLParse: sex is:woman 02-19 21:52:01.391 19388-19388/? D/XMLParse: class is:english 02-19 21:52:01.391 19388-19388/? D/XMLParse: This is Student 02-19 21:52:01.391 19388-19388/? D/XMLParse: name is:xiao ming 02-19 21:52:01.391 19388-19388/? D/XMLParse: age is:15 02-19 21:52:01.391 19388-19388/? D/XMLParse: sex is:man最後一種是Dom方式,Dom方式主要比較耗費內存,需要遍歷所有,一般手機上的app開發不太適用。那就簡單實現下吧,還是利用Async-HttpClient,接著編寫代碼如下:
private void parseXMLWithDom(String xmlData) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
String mName = "";
String mAge = "";
String mSex = "";
String mClass = "";
try {
DocumentBuilder builder = factory.newDocumentBuilder();
//Document document = builder.parse(xmlData);
Document document = builder.parse(new InputSource(new StringReader(xmlData)));
Element root = document.getDocumentElement();
Log.d(TAB, "根節點名稱:" + root.getTagName());
NodeList items = root.getElementsByTagName("Teacher");
Element personElement = (Element)items.item(0);
Log.d(TAB, "根節點名稱:" + personElement.getTagName());
NodeList childNodes = personElement.getChildNodes();
Log.d(TAB, "This is Teacher");
for(int i = 0; i < childNodes.getLength(); i++) {
Node grandElement = childNodes.item(i);
if(grandElement.getNodeType() == Node.ELEMENT_NODE) {
if("name".equals(grandElement.getNodeName())) {
mName = grandElement.getFirstChild().getNodeValue();
Log.d(TAB, "name is:" + mName.trim());
} else if("age".equals(grandElement.getNodeName())) {
mAge = grandElement.getFirstChild().getNodeValue();
Log.d(TAB, "age is:" + mAge.trim());
} else if("sex".equals(grandElement.getNodeName())) {
mSex = grandElement.getFirstChild().getNodeValue();
Log.d(TAB, "sex is:" + mSex.trim());
} else if("class".equals(grandElement.getNodeName())) {
mClass = grandElement.getFirstChild().getNodeValue();
Log.d(TAB, "class is:" + mClass.trim());
}
}
}
} catch (Exception e){
e.printStackTrace();
}
}
02-20 09:16:49.601 1353-1353/? D/XMLParse: 根節點名稱:Person 02-20 09:16:49.601 1353-1353/? D/XMLParse: 根節點名稱:Teacher 02-20 09:16:49.601 1353-1353/? D/XMLParse: This is Teacher:9 02-20 09:16:49.601 1353-1353/? D/XMLParse: name is:xiao hong 02-20 09:16:49.601 1353-1353/? D/XMLParse: age is:25 02-20 09:16:49.601 1353-1353/? D/XMLParse: sex is:woman 02-20 09:16:49.601 1353-1353/? D/XMLParse: class is:english
首先和xml一樣,新建一個person.json文件,如下:
1 [{"name":"xiao hong", "age":"25", "sex":"wonan"},
2 {"name":"xiao ming", "age":"15", "sex":"man"},
3 {"name":"xiao qiang", "age": 30, "sex":"man"}]
保存到和xml同一級目錄下,運行浏覽器如下圖所示:

如圖可知配置已經ok了,那麼接下來就開始完成代碼了,這裡要使用JSONObject和GSON來實現,布局如下:
<!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%2D%2D%3E-->
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:layout_margin="10dp" tools:context="com.jared.emjsonstudy.MainActivity"><button android:id="@+id/getJSONObject" android:text="Get Json With JSONObject" android:layout_width="match_parent" android:layout_height="wrap_content" android:textallcaps="false"></button><button android:id="@+id/getGSON" android:text="Get Json With GSON" android:layout_width="match_parent" android:layout_height="wrap_content" android:textallcaps="false"></button></linearlayout>
package com.jared.emjsonstudy;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import org.json.JSONArray;
import org.json.JSONObject;
import cz.msebera.android.httpclient.Header;
public class MainActivity extends AppCompatActivity {
private static final String TAB = "JSONStudy";
private static final String JSON_URL = "http://192.168.1.102/test/person.json";
private Button mGetJSONObjectBtn;
private Button mGetGSONBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGetJSONObjectBtn = (Button)findViewById(R.id.getJSONObject);
mGetGSONBtn = (Button)findViewById(R.id.getGSON);
mGetJSONObjectBtn.setOnClickListener(new myOnClickListener());
mGetGSONBtn.setOnClickListener(new myOnClickListener());
}
private class myOnClickListener implements View.OnClickListener {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.getJSONObject:
getJSONWithJSONObject(JSON_URL);
break;
case R.id.getGSON:
break;
default:
break;
}
}
}
private void parseJSONWithJSONObject(String jsonData) {
try {
JSONArray jsonArray = new JSONArray(jsonData);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String mName = jsonObject.getString("name");
String mAge = jsonObject.getString("age");
String mSex = jsonObject.getString("sex");
Log.d(TAB, "name is: " + mName);
Log.d(TAB, "age is: " + mAge);
Log.d(TAB, "sex is:" + mSex);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void getJSONWithJSONObject(String url) {
AsyncHttpClient client = new AsyncHttpClient();
client.get(url, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int i, Header[] headers, byte[] bytes) {
try {
String response = new String(bytes, 0, bytes.length, "utf-8");
parseJSONWithJSONObject(response);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
}
});
}
}
02-20 10:13:20.521 4947-4947/? D/JSONStudy: name is: xiao hong 02-20 10:13:20.521 4947-4947/? D/JSONStudy: age is: 25 02-20 10:13:20.521 4947-4947/? D/JSONStudy: sex is:wonan 02-20 10:13:20.521 4947-4947/? D/JSONStudy: name is: xiao ming 02-20 10:13:20.521 4947-4947/? D/JSONStudy: age is: 15 02-20 10:13:20.521 4947-4947/? D/JSONStudy: sex is:man 02-20 10:13:20.521 4947-4947/? D/JSONStudy: name is: xiao qiang 02-20 10:13:20.521 4947-4947/? D/JSONStudy: age is: 30 02-20 10:13:20.521 4947-4947/? D/JSONStudy: sex is:man
接著使用google的開源庫GSON來實現,用到開源庫,那就先下載了。gson下載地址:GSON下載地址點擊這裡。gson gitbub地址:https://github.com/google/gson。
GSON庫主要是將一段JSON格式的字符串自動映射成一個對象,從而不需要編寫代碼去解析。這裡新建一個Person類來獲取數據,代碼如下:
package com.jared.emjsonstudy;
/**
* Created by jared on 16/2/20.
*/
public class Person {
private String name;
private String age;
private String sex;
public String getName() {
return name;
}
public String getAge() {
return age;
}
public String getSex() {
return sex;
}
public void setName(String name) {
this.name = name;
}
public void setAge(String age) {
this.age = age;
}
public void setSex(String sex) {
this.sex = sex;
}
}
void parseJSONWithGSON(String jsonData) {
Gson gson = new Gson();
List personList = gson.fromJson(jsonData,
new TypeToken>(){}.getType());
for (Person person :personList) {
Log.d(TAB, "Gson: name is: " + person.getName());
Log.d(TAB, "Gson: age is: " + person.getAge());
Log.d(TAB, "Gson: sex is:" + person.getSex());
}
}
void getJSONWithGSON(String url) {
AsyncHttpClient client = new AsyncHttpClient();
client.get(url, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int i, Header[] headers, byte[] bytes) {
try {
String response = new String(bytes, 0, bytes.length, "utf-8");
parseJSONWithGSON(response);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
}
});
}
02-20 10:42:56.381 6434-6434/? D/JSONStudy: Gson: name is: xiao hong 02-20 10:42:56.381 6434-6434/? D/JSONStudy: Gson: age is: 25 02-20 10:42:56.381 6434-6434/? D/JSONStudy: Gson: sex is:wonan 02-20 10:42:56.381 6434-6434/? D/JSONStudy: Gson: name is: xiao ming 02-20 10:42:56.381 6434-6434/? D/JSONStudy: Gson: age is: 15 02-20 10:42:56.381 6434-6434/? D/JSONStudy: Gson: sex is:man 02-20 10:42:56.381 6434-6434/? D/JSONStudy: Gson: name is: xiao qiang 02-20 10:42:56.381 6434-6434/? D/JSONStudy: Gson: age is: 30 02-20 10:42:56.381 6434-6434/? D/JSONStudy: Gson: sex is:man當然如果想要生存json數據,也是可以用gson的tojson方法的。
Android Tab -- 使用ViewPager、Fragment、FragmentPagerAdapter來實現
效果:滑動切換;點擊標簽切換。 代碼:https://github.com/ldb-github/Layout_Tab1、布局:使用LinearLayout布置
Bluestacks安卓模擬器簡單設置使用圖解教程
Bluestacks是一個可以讓Android應用程序運行在電腦(現在包括windows系統,mac版)的一種模擬器,就是我們在電腦上也可以運行Androi
Android中Android Virtual Device(AVD)使用教程
AVD的全稱為:Android Virtual Device,就是Android運行的虛擬設備,他是Android的模擬器識別。建立的Android要運行,必須創建AVD
第四十四講:Android之Dialog 對話框(一)
終身學習,不斷讀書,以書為侶,是我們每個人不讓自己的生命過早枯萎的唯一選擇。為了讓我們的生命之樹常青,讓我們今後的生活更加豐富多彩,朋友們,讓我們一起來努力吧! 本