Android开发学习之路--网络编程之xml、json
一般网络数据通过http来get,post,那么其中的数据不可能杂乱无章,比如我要post一段数据,肯定是要有一定的格式,协议的。常用的就是xml和json了。在此先要搭建个简单的服务器吧,首先呢下载xampp,然后安装之类的就不再多讲了,参考http://cnbin.github.io/blog/2015/06/05/mac-an-zhuang-he-shi-yong-xampp/。安装好后,启动xampp,之后在浏览器输入localhost或者127.0.0.1就可以看到如下所示了:
这个就表示服务器已经运行了,具体的代码都是放在这个/Applications/XAMPP/htdocs目录下的。然后待会儿编写个xml文件也放在这里。
编写个简单的xml文件吧。
<Person>
2 <Teacher>
3 <name>xiao hong</name>
4 <age>25</age>
5 <sex>woman</sex>
6 <class>english</class>
7 </Teacher>
8 <Student>
9 <name>xiao ming</name>
10 <age>15</age>
11 <sex>man</sex>
12 </Student>
13 </Person>
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 { }
}
这里要使用三种方法,所以修改布局如下:
<?xml version="1.0" encoding="utf-8"?>
<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
android:id="@+id/getXmlpull"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Pull方式获取"/> <Button
android:id="@+id/getXmldom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Dom方式获取"/> </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();
}
}
}
这里用到了AsyncHttpClient,具体库的添加参考上一篇文章Android开发学习之路--网络编程之初体验。好了,这里在发送请求的时候,成功再调用parseXMLWithSax进行解析。这里的地址是192.168.1.102,因为是真机调试,连接到了同一个网段,然后手机就可以访问我们的服务器了。
实例化一个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();
}
}
这里简单的就实现了Teacher的,student的就没有添加,相信也是很容易的了,其余的代码和上述类似,运行效果如下:
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基本上先学习这些知识了。接着学习json的知识。
首先和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来实现,布局如下:
<?xml version="1.0" encoding="utf-8"?>
<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
android:id="@+id/getGSON"
android:text="Get Json With GSON"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"/> </LinearLayout>
接着实现代码,还是用了Async-HttpClient来实现,代码如下:
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) { }
});
}
}
如上代码明显比xml的简单多了,JSONArray获取到Json数据,然后通过JSONObject来获取对应键值的内容。因为我的电脑ip地址是192.168.1.102,手机和电脑在同一个网段,所以直接利用真机来测试,效果如下:
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;
}
}
MainActivity中添加代码:
void parseJSONWithGSON(String jsonData) {
Gson gson = new Gson();
List<Person> personList = gson.fromJson(jsonData,
new TypeToken<List<Person>>(){}.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) { }
});
}
这里new了一个Gson,然后通过fromJson的方法,通过TypeToken获取数据并保存到Person列表中。运行看下效果:
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开发学习之路--网络编程之xml、json的更多相关文章
- Android开发学习之路--网络编程之初体验
一般手机都是需要上网的,一般我们的浏览器就是个webview.这里简单实现下下功能,先编写Android的layout布局: <?xml version="1.0" enco ...
- Android开发学习之路--Android系统架构初探
环境搭建好了,最简单的app也运行过了,那么app到底是怎么运行在手机上的,手机又到底怎么能运行这些应用,一堆的电子元器件最后可以运行这么美妙的界面,在此还是需要好好研究研究.这里从芯片及硬件模块-& ...
- GO语言的进阶之路-网络编程之socket
GO语言的进阶之路-网络编程之socket 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是socket; 在说socket之前,我们要对两个概念要有所了解,就是IP和端口 ...
- Android开发学习之路-RecyclerView滑动删除和拖动排序
Android开发学习之路-RecyclerView使用初探 Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析 Android开 ...
- Android开发学习之路--基于vitamio的视频播放器(二)
终于把该忙的事情都忙得差不多了,接下来又可以开始good good study,day day up了.在Android开发学习之路–基于vitamio的视频播放器(一)中,主要讲了播放器的界面的 ...
- Android开发学习之路--Android Studio cmake编译ffmpeg
最新的android studio2.2引入了cmake可以很好地实现ndk的编写.这里使用最新的方式,对于以前的android下的ndk编译什么的可以参考之前的文章:Android开发学习之路– ...
- Android开发学习之路--Activity之初体验
环境也搭建好了,android系统也基本了解了,那么接下来就可以开始学习android开发了,相信这么学下去肯定可以把android开发学习好的,再加上时而再温故下linux下的知识,看看androi ...
- Android开发学习之路--MAC下Android Studio开发环境搭建
自从毕业开始到现在还没有系统地学习android应用的开发,之前一直都是做些底层的驱动,以及linux上的c开发.虽然写过几个简单的app,也对android4.0.3的源代码做过部分的分析,也算入门 ...
- 我的大学Android开发学习之路——从开始到微信/支付宝/抖音Offer
前言 笔者2016年高考考入华中科技大学计算机科学与技术专业. 2017年底(大二寒假)拿到今日头条(字节跳动)深圳研发中心Android开发实习生Offer,在深圳研发中心实习至2018年3月. 2 ...
随机推荐
- 试说明采用双缓冲技术如何进行I/O操作
输入设备先将第一个缓冲区装满数据,在输入设备向第二个缓冲区装数据时,处理机就可以从第一个缓冲区取出数据进行处理:当一个缓冲区的数据处理完毕,若第二个缓冲区已经装满,则处理机又可以从第二个缓冲区取出数据 ...
- Python 中的 if __name__ == '__main__' 该如何理解
__name__ 表示当前模块名, __main__ 表示正在运行的模块名. if __name__ == '__main__' 这句话的意思就是,当模块被直接运行时,以下代码块将被运行,当模块是被导 ...
- 华科机考:N阶楼梯上楼
时间限制:1秒空间限制:32768K 题目描述 N阶楼梯上楼问题:一次可以走两阶或一阶,问有多少种上楼方式.(要求采用非递归) 输入描述: 输入包括一个整数N,(1<=N<90). 输出描 ...
- C语言程序设计第六次作业--循环结构(2)
(一)改错题 序列求和:输入一个正实数eps,计算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... ,精确到最后一项的绝对值小于eps(保留6位小数). 输入输出样例: Input e ...
- Java8-理解Colloctor
上一节学习了Java8中比较常用的内置collector的用法.接下来就来理解下collector的组成. Collector定义 Collector接口包含了一系列方法,为实现具体的归约操作(即收集 ...
- C++中的各种可调用对象
概述 一组执行任务的语句都可以视为一个函数,一个可调用对象.在程序设计的过程中,我们习惯于把那些具有复用性的一组语句抽象为函数,把变化的部分抽象为函数的参数. 函数的使用能够极大的极少代码重复率,提高 ...
- SUSE11虚拟机安装与Oracle 11g安装
SUSE11虚拟机安装与Oracle 11g安装 本文中所需所有参数均位于文末附录中 新建虚拟机,选择SUSE11 64位 启动虚拟机后,选择第二项安装 选择语言 跳过CD检查 选择全新安装 选择默认 ...
- 使用ajax上传图片,支持图片即时浏览,支持js图片压缩后上传给服务器
使用ajax上传图片,支持图片即时浏览,支持js图片压缩后上传给服务器 ajax上传主要使用了 var reader = new FileReader() 此方法 js图片压缩主要是利用canvas进 ...
- jQuery 效果 – 隐藏和显示
在 jQuery 中可以使用 hide() 和 show() 方法来隐藏和显示 HTML 元素,以及使用 toggle() 方法能够切换 hide() 和 show() 方法. 隐藏.显示.切换,滑动 ...
- Docker 列出镜像
使用 docker images 显示本地已有的镜像. $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu ...