android网络通信 接收和发送数据详解

android网络通信 接收和发送数据详解
android网络通信 接收和发送数据详解

一、从网络上获取数据(图片、网页、XML、JSON等)

1.从网络获取一张图片,然后显示在手机上

[java]view plaincopy

1.①public byte [] getImageFromNet(){

2.try {

3. URL url = new URL("https://www.360docs.net/doc/235594584.html,/n1/4987/9dceed99-e710-4ca8-

b7f1-4e9dc01a0f75.jpg");

4. HttpURLConnection conn = (HttpURLConnection)url.openConnection();

5. conn.setRequestMethod("GET");

6. conn.setConnectTimeout(5 * 1000);

7. conn.connect();

8. InputStream inStream = conn.getInputStream();

9.byte [] data = readInputStream(inStream);//获取图片的二进制数据

10.//FileOutputStream outStream = new FileOutputStream("360buy.jpg");

11.//outStream.write(data);

12.//outStream.close();

13.return data;

14. } catch (Exception e) {

15. e.printStackTrace();

16. }

17. }

18.private byte [] readInputStream(InputStream inStream) throws IOException {

19. ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();

20.byte[] buffer = new byte[1024];

21.int len = -1;

22.while((len = inStream.read(buffer)) != -1){

23. byteOutputStream.write(buffer, 0, len);

24. }

25. inStream.close();

26.byte [] data = byteOutputStream.toByteArray();

27. byteOutputStream.close();

28.return data;

29. }

②使用ImageView组件显示图片。

③生成位图并设置到ImageView中

[java]view plaincopy

1.Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

2. imageView.setImageBitmap(bitmap);

④在AndroidManifest.xml文件添加网络访问权限:

[java]view plaincopy

1.

2.从网络获取指定网页的html代码,然后显示在手机上

[java]view plaincopy

1.①public String getHtmlCodeFromNet(){

2.try {

3. URL url = new URL("https://www.360docs.net/doc/235594584.html,");

4. HttpURLConnection conn = (HttpURLConnection)url.openConnection();

5. conn.setRequestMethod("GET");

6. conn.setConnectTimeout(5 * 1000);

7. conn.connect();

8. InputStream inStream = conn.getInputStream();

9.byte [] data = readInputStream(inStream);

10. String htmlString = new String(data, "gb2312");

11. System.out.println(htmlString);

12.return htmlString;

13. } catch (Exception e) {

14. e.printStackTrace();

15. }

16. }

②使用TextView组件显示网页代码

ScrollView 滚动条

[java]view plaincopy

1.

2. android:layout_width="fill_parent"

3. android:layout_height="fill_parent">

4.

5. android:layout_width="fill_parent"

6. android:layout_height="wrap_content"

7. android:id="@+id/textView"

8. />

9.

③在AndroidManifest.xml文件添加网络访问权限:

[java]view plaincopy

1.

3.从服务器上获取最新的视频资讯信息,该信息以XML格式返回给Android客户端,然后列表显示在手机上。

>>最新资讯

喜羊羊与灰太狼时长:60

盗梦空间时长:120

生化危机时长:100

①开发web端,在此采用Struts 2技术

②设计显示界面,使用ListView

③开发Android手机视频资讯客户端

注意:不能使用127.0.0.1或者localhost访问在本机开发的web应用

部分代码:

[java]view plaincopy

1.public List

2. URL url = new URL(urlPath);

3. HttpURLConnection conn = (HttpURLConnection)url.openConnection();

4. conn.setRequestMethod("GET");

5. conn.setConnectTimeout(5 * 1000);

6. conn.connect();

7. InputStream inStream = conn.getInputStream();

8.return parseXML(inStream);

9.}

[java]view plaincopy

1.private List

2. List

3. Video video = null;

4. XmlPullParser parser = Xml.newPullParser();

5. parser.setInput(inStream, "UTF-8");

6.int eventType = parser.getEventType();

7.while(eventType != XmlPullParser.END_DOCUMENT){

8.switch (eventType) {

9.case XmlPullParser.START_DOCUMENT:

10. videos = new ArrayList

11.break;

12.case XmlPullParser.START_TAG:

13. String name = parser.getName();

14.if("video".equals(name)){

15. video = new Video();

16. video.setId(new Integer(parser.getAttributeValue(0)));

17. }

18.if(video != null){

19.if("title".equals(name)){

20. video.setTitle(parser.nextText());

21. }else if("timeLength".equals(name)){

22. video.setTimeLength(new Integer(parser.nextText()));

23. }

24. }

25.break;

26.case XmlPullParser.END_TAG:

27. String pname = parser.getName();

28.if("video".equals(pname)){

29. videos.add(video);

30. video = null;

31. }

32.break;

33.default:

34.break;

35. }

36. eventType = parser.next();

37. }

38.return videos;

39.}

④在AndroidManifest.xml文件添加网络访问权限:

[java]view plaincopy

1.

4.从服务器上获取最新的视频资讯信息,该信息以JSON格式返回给Android客户端,然后列表显示在手机上。

服务器端需要返回的JSON数据:

[java]view plaincopy

1.[{id:1,title:"aaa1",timeLength:50},{id:2,title:"aaa2",timeLength:50},{id:3,t

itle:"aaa3",timeLength:50}]

[java]view plaincopy

1.public List

2. URL url = new URL(urlPath);

3. HttpURLConnection conn = (HttpURLConnection)url.openConnection();

4. conn.setRequestMethod("GET");

5. conn.setConnectTimeout(5 * 1000);

6. conn.connect();

7. InputStream inStream = conn.getInputStream();

8.byte [] data = StreamTools.readInputStream(inStream);

9. String json = new String(data);

10. JSONArray array = new JSONArray(json);

11. List

12.for(int i = 0;i < array.length(); i++){

13. JSONObject item = array.getJSONObject(i);

14.int id = item.getInt("id");

15. String title = item.getString("title");

16.int timeLength = item.getInt("timeLength");

17. videos.add(new Video(id, title, timeLength));

18. }

19.return videos;

20.}

二、通过HTTP协议提交文本数据(GET/POST)

GET、POST、HttpClient

1.通过GET方式提交参数给服务器:注意处理乱码(Android系统默认编码是UTF-8),提交的数据最大2K。

①服务器端代码

[java]view plaincopy

1.HttpServletRequest request = ServletActionContext.getRequest();

2.//服务器端编码处理,先以ISO-8859-1编码得到二进制数据,然后使用UTF-8对数据重新编码

3.byte [] data = request.getParameter("title").getBytes("ISO-8859-1");

4.String titleString = new String(data, "UTF-8");

5.System.out.println("this.title==" + titleString);

6.System.out.println("this.timeLength==" + this.timeLength);

②客户端代码

[java]view plaincopy

1.public boolean sendGetRequest(String path, Map params, Strin

g enc) throws Exception{

2. StringBuilder sb = new StringBuilder(path);

3. sb.append('?');

4.if(params != null && !params.isEmpty()){

5.for(Map.Entry entry : params.entrySet()){

6. sb.append(entry.getKey())

7. .append('=')

8.//对客户端发送GET请求的URL重新编码

9. .append(URLEncoder.encode(entry.getValue(), enc))

10. .append('&');

11. }

12. sb.deleteCharAt(sb.length()-1);

13. }

14. URL url = new URL(sb.toString());

15. HttpURLConnection conn = (HttpURLConnection) url.openConnection();

16. conn.setRequestMethod("GET");

17. conn.setConnectTimeout(5 * 1000);

18.if(conn.getResponseCode() == 200){

19.return true;

20. }

21.return false;

}

2. 通过POST方式提交参数给服务器:

浏览器会把提交的数据转换成Http协议

②分析Http协议(使用HttpWatch)

第一部分:发送给服务器的

请求头部分(**********表示Http协议中必须提供的部分)

[java]view plaincopy

1.POST /videoweb/managerPost.action HTTP/1.1---(请求方式请求路径使用Http协议是

1.1)

2.Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shock

wave-flash, application/vnd.ms-excel,

3.application/vnd.ms-powerpoint, application/msword, application/QVOD, applica

tion/QVOD, */* ---(浏览器接收的数据类型)

4.Referer: http://127.0.0.1:8081/videoweb/index.jsp---(请求来源,即从哪个页面发出

请求的)

5.Accept-Language: zh-cn,en-US;q=0.5

https://www.360docs.net/doc/235594584.html,er-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0;

CIBA; .NET CLR 2.0.50727) ---(用户的浏览器类型)

7.Content-Type: application/x-www-form-urlencoded ---(POST请求的内容类

型)**********

8.Accept-Encoding: gzip, deflate

9.Host: 127.0.0.1:8081 ---(POST请求的服务器主机名和端口)**********

10.Content-Length: 46 ---(POST请求的内容长度,即实体数据部分的长度)**********

11.Connection: Keep-Alive ---(长连接)

12.Cache-Control: no-cache

13.Cookie: JSESSIONID=EFD762A0997BE1191DABFC311B345EE7

实体数据部分

[java]view plaincopy

1.title=aaa&timeLength=22&sub=%E6%8F%90%E4%BA%A4

第二部分:客户端接收到的

[java]view plaincopy

1.HTTP/1.1200 OK

2.Server: Apache-Coyote/1.1

3.Content-Type: text/html;charset=UTF-8

4.Content-Length: 275

5.Date: Sun, 06 Mar 201110:57:55 GMT

6.

7.

https://www.360docs.net/doc/235594584.html,/TR/html4/loose.dtd">

8.

9.

10.

11.Insert title here

12.

13.

14.淇濆瓨瀹屾垚锛?

15.

16.

③服务器端代码

[java]view plaincopy

1.HttpServletRequest request = ServletActionContext.getRequest();

2.request.setCharacterEncoding("UTF-8");

3.System.out.println("doPostRequest");

4.System.out.println("this.title==" + this.title);

5.System.out.println("this.timeLength==" + this.timeLength);

④客户端代码

[java]view plaincopy

1.public boolean sendPostRequest(String path, Map params, Stri

ng enc) throws Exception{

2.//分析http协议

3.//发出post请求时,浏览器会自动为实体数据部分进行重新编码。由于我们使用的是Android,

没有用IE浏览器,因此需要手动对URL重新编码。

4.//username=%E5%BC%A0%E4%B8%89&sub=%E7%99%BB%E9%99%86

5. StringBuilder sb = new StringBuilder();

6.if(params != null && !params.isEmpty()){

7.for(Map.Entry entry : params.entrySet()){

8. sb.append(entry.getKey())

9. .append('=')

10.//对客户端post请求的URL手动重新编码

11. .append(URLEncoder.encode(entry.getValue(), enc))

12. .append('&');

13. }

14. sb.deleteCharAt(sb.length()-1);

15. }

16. URL url = new URL(path);

17. HttpURLConnection conn = (HttpURLConnection) url.openConnection();

18. conn.setRequestMethod("POST");

19. conn.setConnectTimeout(5 * 1000);

20.//如果通过post提交数据,必须设置允许对外输出数据。

21. conn.setDoOutput(true);

22.//Content-Type: application/x-www-form-urlencoded

23.//Content-Length: 46 获取实体数据的二进制长度

24.byte [] data = sb.toString().getBytes();

25.//设置请求属性

26. conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"

);

27. conn.setRequestProperty("Content-Length", String.valueOf(data.length));

28. OutputStream outputStream = conn.getOutputStream();

29. outputStream.write(data);

30. outputStream.flush();

31. outputStream.close();

32.if(conn.getResponseCode() == 200){

33.return true;

34. }

35.return false;

36.}

3.使用HttpClient开源项目提交参数给服务器

①服务器端代码

[java]view plaincopy

1.HttpServletRequest request = ServletActionContext.getRequest();

2.request.setCharacterEncoding("UTF-8");

3.System.out.println("this.title==" + this.title);

4.System.out.println("this.timeLength==" + this.timeLength);

②客户端代码

[java]view plaincopy

1.public boolean sendRequestByHttpClient(String path, Map para

ms, String enc) throws Exception{

2.//名值对

3. List paramPairs = new ArrayList();

4.if(params != null && !params.isEmpty()){

5.for(Map.Entry entry : params.entrySet()){

6. paramPairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));

7. }

8. }

9.//对实体数据进行重新编码

10. UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramPairs, enc);

11.//相当于form

12. HttpPost post = new HttpPost(path);

13. post.setEntity(entity);

14.//相当于客户端浏览器

15. DefaultHttpClient client = new DefaultHttpClient();

16.//执行请求

17. HttpResponse response = client.execute(post);

18.if(response.getStatusLine().getStatusCode() == 200){

19.return true;

20. }

21.return false;

22.}

三、通过HTTP协议上传文件数据

分析上传文件的HTTP协议

Content-Type: multipart/form-data; boundary=---------------------------7db1861b605fa

实体数据分隔线:用于分隔每一个请求参数

示例:

(1)定义部分:boundary=---------------------------7db1861b605fa

(2)实体数据部分:-----------------------------7db1861b605fa(多出两个--)

-----------------------------7db1861b605fa--(最后的--表示实体数据部分结束)

服务器对上传文件大小有限制,一般最大是2M(文件过大时不建议使用HTTP协议)。[java]view plaincopy

1./**

2. * 上传文件

3. */

4.public class FormFile {

5./* 上传文件的数据 */

6.private byte[] data;

7.private InputStream inStream;

8.private File file;

9./* 文件名称 */

10.private String filename;

11./* 请求参数名称*/

12.private String parameterName;

13./* 内容类型 */

14.private String contentType = "application/octet-stream";

15.//上传小容量的文件建议使用此构造方法

16.public FormFile(String filename, byte[] data, String parameterName, String

contentType) {

17.this.data = data;

18.this.filename = filename;

19.this.parameterName = parameterName;

20.if(contentType != null)

21.this.contentType = contentType;

22. }

23.//上传大容量的文件建议使用此构造方法

24.public FormFile(String filename, File file, String parameterName, String co

ntentType) {

25.this.filename = filename;

26.this.parameterName = parameterName;

27.this.file = file;

28.try {

29.this.inStream = new FileInputStream(file);

30. } catch (FileNotFoundException e) {

31. e.printStackTrace();

32. }

33.if(contentType != null)

34.this.contentType = contentType;

35. }

36.

37. ..................................

38.

39.}

40.public static boolean post(String path, Map params, FormFile

[] files) throws Exception {

41.// 定义客户端socket对象

42. Socket socket = null;

43.// 定义字节输入流对象

44. OutputStream outStream = null;

45.// 定义字符输入流对象

46. BufferedReader reader = null;

47.try{

48.// 定义数据分隔线

49.final String BOUNDARY = "---------------------------7db1861b605fb";

50.// 定义数据结束标志

51.final String ENDLINE = "--" + BOUNDARY + "--\r\n";

52.

53.// 获取实体数据内容及其总长度

54.// 定义保存文本类型实体数据的字符串

55. StringBuilder textEntity = new StringBuilder();

56.int textDataLength = 0;

57.// 1、获取文本类型参数的实体数据及长度

58.for (Map.Entry entry : params.entrySet()) {

59. textEntity.append("--");

60. textEntity.append(BOUNDARY);

61. textEntity.append("\r\n");

62. textEntity.append("Content-Disposition: form-data; name=\"" + entry.getKe

y() + "\"\r\n\r\n");

63. textEntity.append(entry.getValue());

64. textEntity.append("\r\n");

65. }

66.byte [] textData = textEntity.toString().getBytes(enc);

67. textDataLength = textData.length;

68.

69.int fileDataLength = 0;

70.// 定义保存文件类型实体数据的字符串

71. StringBuilder fileEntity = new StringBuilder();

72.byte [] fileData = null;

73.// 2、获取文件类型参数的实体数据及长度

74.for (FormFile uploadFile : files) {

75. fileEntity.append("--");

76. fileEntity.append(BOUNDARY);

77. fileEntity.append("\r\n");

78. fileEntity.append("Content-Disposition: form-data;name=\""

79. + uploadFile.getParameterName() + "\";filename=\""

80. + uploadFile.getFilename() + "\"\r\n");

81. fileEntity.append("Content-Type: " + uploadFile.getContentType() + "\r\n\

r\n");

82. fileData = fileEntity.toString().getBytes(enc);

83. fileDataLength += fileData.length;

84. fileDataLength += "\r\n".getBytes(enc).length;

85.if (uploadFile.getInStream() != null) {

86. fileDataLength += uploadFile.getFile().length();

87. } else {

88. fileDataLength += uploadFile.getData().length;

89. }

90. }

91.// 计算传输给服务器的实体数据总长度

92.int dataLength = textDataLength + fileDataLength + ENDLINE.getBytes(enc).l

ength;

93. System.out.println("dataLength: " + dataLength);

94.

95.// 编写HTTP协议发送数据

96. URL url = new URL(destpath);

97.int port = url.getPort() == -1 ? 80 : url.getPort();

98. System.out.println("url.getHost(): " + url.getHost());

99. System.out.println("port: " + port);

100.// 创建Socket连接

101. socket = new Socket(InetAddress.getByName(url.getHost()), port);

102.// 获取输入流对象

103. outStream = socket.getOutputStream();

104./** 下面完成HTTP请求头的发送 start **/

105. StringBuilder requestHead = new StringBuilder();

106. requestHead.append("POST " + url.getPath() + " HTTP/1.1\r\n");

107. requestHead.append("Accept: image/gif, image/jpeg, image/pjpeg, image/pjp eg, application/x-shockwave-flash, application/xaml+xml, " + 108."application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-m s-application, application/vnd.ms-excel, " +

109."application/vnd.ms-powerpoint, application/msword, */*\r\n");

110. requestHead.append("Accept-Language: zh-CN\r\n");

111. requestHead.append("Content-Type: multipart/form-data; boundary=" + BOUND ARY + "\r\n");

112. requestHead.append("Host: " + url.getHost() + ":" + port + "\r\n"); 113. requestHead.append("Content-Length: " + dataLength + "\r\n");

114. requestHead.append("Connection: Keep-Alive\r\n");

115.// 根据HTTP协议在HTTP请求头后面需要再写一个回车换行

116. requestHead.append("\r\n".getBytes(enc));

117. outStream.write(requestHead.toString().getBytes(enc));

118. /** 上面完成HTTP请求头的发送 end **/

119.

120./** 下面发送实体数据 start **/

121.// 发送所有文本类型的实体数据

122. outStream.write(textData);

123.// 发送所有文件类型的实体数据

124.for (FormFile uploadFile : files) {

125.// 发送文件类型实体数据

126. outStream.write(fileData);

127.

128.// 发送文件数据

129.if (uploadFile.getInStream() != null) {

130.byte[] buffer = new byte[1024];

131.int len = 0;

132.while ((len = uploadFile.getInStream().read(buffer)) != -1) {

133. outStream.write(buffer, 0, len);

134. }

135. uploadFile.getInStream().close();

136. } else {

137. outStream.write(uploadFile.getData(), 0, uploadFile.getData().length);

138. }

139. outStream.write("\r\n".getBytes(enc));

140. }

141.// 发送数据结束标志,表示数据已经结束

142. outStream.write(ENDLINE.getBytes(enc));

143. outStream.flush();

144./** 上面发送实体数据 end **/

145.

146.// 判断数据发送是否成功

147. reader = new BufferedReader(new InputStreamReader(socket.getInputStream() ));

148. String content = reader.readLine();

149. System.out.println("content: " + content);

150.// 读取web服务器返回的数据,判断请求码是否为200,如果不是200,代表请求失败151.if (content.indexOf("200") == -1) {

152.return false;

153. }

154. } catch(Exception e){

155.throw e;

156. } finally {

157.if(outStream != null){

158. outStream.close();

159. }

160.if(reader != null){

161. reader.close();

162. }

163.if(socket != null){

164. socket.close();

165. }

166. }

167.return true;

168.}

169.

170.

171.

172.

173.

174.

四、通过HTTP协议发送XML数据(作为实体数据,不是作为请求参数),并调用WebService 调用WebService时需要发送XML实体数据

1、发送XML数据给服务器

[java]view plaincopy

1.public boolean sendXML(String path, String xml) throws Exception{

2.byte [] data = xml.getBytes();

3. URL url = new URL(path);

4. HttpURLConnection conn = (HttpURLConnection) url.openConnection();

5. conn.setRequestMethod("POST");

6. conn.setConnectTimeout(5 * 1000);

7. conn.setDoOutput(true);

8. conn.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");

9. conn.setRequestProperty("Content-Length", String.valueOf(data.length));

10. OutputStream outputStream = conn.getOutputStream();

11. outputStream.write(data);

12. outputStream.flush();

13. outputStream.close();

14.if(conn.getResponseCode() == 200){

15.return true;

16. }

17.return false;

18.}

2、发送SOAP数据给服务器调用WebService,实现手机号归属地查询

SOAP协议基于XML格式

https://www.360docs.net/doc/235594584.html,/

https://www.360docs.net/doc/235594584.html,/WebServices/MobileCodeWS.asmx

SOAP 1.2 请求示例。所显示的[]需替换为实际值。

[java]view plaincopy

1.POST /WebServices/MobileCodeWS.asmx HTTP/1.1

2.Host: https://www.360docs.net/doc/235594584.html,

3.Content-Type: application/soap+xml; charset=utf-8

4.Content-Length: length

5.

6.

7.

:xsd="https://www.360docs.net/doc/235594584.html,/2001/XMLSchema" xmlns:soap12="https://www.360docs.net/doc/235594584.html,/2003 /05/soap-envelope">

8.

9.

10. [string]

11. [string]

12.

13.

14.

SOAP 1.2 响应示例。所显示的[]需替换为实际值。

SOAP 1.2 响应示例。所显示的[]需替换为实际值。

[java]view plaincopy

1.HTTP/1.1200 OK

2.Content-Type: application/soap+xml; charset=utf-8

3.Content-Length: length

4.

5.

6.

:xsd="https://www.360docs.net/doc/235594584.html,/2001/XMLSchema" xmlns:soap12="https://www.360docs.net/doc/235594584.html,/2003 /05/soap-envelope">

7.

8.

9. [string]

10.

11.

12.

[java]view plaincopy

1./**

2. * 发送SOAP数据给服务器调用WebService,实现手机号归属地查询

3. * @param path

4. * @param soapXML

5. * @return

6. * @throws Exception

7. */

8.public String getMobileCodeInfo(String path, InputStream inStream, String mo

bileCode) throws Exception{

9. String soapXML = readSoapXML(inStream, mobileCode);

10.byte [] data = soapXML.getBytes();

11. URL url = new URL(path);

12. HttpURLConnection conn = (HttpURLConnection) url.openConnection();

13. conn.setRequestMethod("POST");

14. conn.setConnectTimeout(5 * 1000);

15. conn.setDoOutput(true);

16. conn.setRequestProperty("Content-Type", "application/soap+xml; charset=utf-

8");

17. conn.setRequestProperty("Content-Length", String.valueOf(data.length));

18. OutputStream outputStream = conn.getOutputStream();

19. outputStream.write(data);

20. outputStream.flush();

21. outputStream.close();

22.if(conn.getResponseCode() == 200){

23.//byte [] responseData = StreamTools.readInputStream(conn.getInputStream()

);

24.//String responseXML = new String(responseData);

25.//return responseXML;

26.

27.return parseResponseXML(conn.getInputStream());

28. }

29.return null;

30.}

31.private String parseResponseXML(InputStream inStream) throws Exception{

32. XmlPullParser parser = Xml.newPullParser();

33. parser.setInput(inStream, "UTF-8");

34.int eventType = parser.getEventType();

35.while(eventType != XmlPullParser.END_DOCUMENT){

36.switch (eventType) {

37.case XmlPullParser.START_TAG:

38. String name = parser.getName();

39.if("getMobileCodeInfoResult".equals(name)){

40.return parser.nextText();

41. }

42.break;

43. }

44. eventType = parser.next();

45. }

46.return null;

47.}

48./**

49. * 读取MobileCodeWS.xml(要符合SOAP协议),并且替换其中的占位符

50. * @param inStream

51. * @param mobileCode 真实手机号码

52. * @return

53. * @throws Exception

54. */

55.public String readSoapXML(InputStream inStream, String mobileCode) throws Ex

ception{

56.byte [] data = StreamTools.readInputStream(inStream);

57. String soapXML = new String(data);

58. Map params = new HashMap();

59. params.put("mobileCode", mobileCode);

60.//替换掉MobileCodeWS.xml中占位符处的相应内容

61.return replace(soapXML, params);

62.}

63.private String replace(String soapXML, Map params) throws Ex

ception{

64. String result = soapXML;

65.if(params != null && !params.isEmpty()){

66.for(Map.Entry entry : params.entrySet()){

67. String regex = "\\*"+ entry.getKey();

68. Pattern pattern = https://www.360docs.net/doc/235594584.html,pile(regex);

69. Matcher matcher = pattern.matcher(result);

70.if(matcher.find()){

71. result = matcher.replaceAll(entry.getValue());

72. }

73. }

74. }

75.return result;

76.}

五、通过HTTP协议实现多线程断点下载

使用多线程下载文件可以提高文件下载的速度,更快完成文件的下载。多线程下载文件之所

以快,是因为其抢占的服务器资源多。假设服务器同时最多服务100个用户,在服务器中一条线程对应一个用户,100条线程在计算机中并非并发执行,而是由CPU划分时间片轮流执行,如果A用户使用了99条线程下载文件,那么相当于占用了99个用户的资源,如果一秒内CPU分配给每条线程的平均执行时间是10ms,A用户在服务器中一秒内就得到了990ms的执行时间,而其他用户在一秒内只有10ms的执行时间。好比一个水龙头,每秒出水量相等的情况下,放990毫秒的水肯定比放10毫秒的水要多。

1、多线程下载的实现过程:

①、首先得到下载文件的长度,然后设置本地文件的长度。

[java]view plaincopy

1.//获取下载文件的长度

2.int fileLength = HttpURLConnection.getContentLength();

3.//在本地硬盘创建和需下载文件长度相同的文件。

4.RandomAccessFile file = new RandomAccessFile("QQ2011.exe", "rwd");

5.//设置本地文件的长度和下载文件长度相同

6.file.setLength(fileLength);

7.file.close();

②、根据文件长度和线程数计算每条线程下载的数据长度和下载位置。

a:每条线程下载的数据长度:文件长度% 线程数== 0 ? 文件长度/ 线程数: 文件长度/ 线程数+ 1

例如:文件的长度为6M,线程数为3,那么每条线程下载的数据长度为2M。

b:每条线程从文件的什么位置开始下载到什么位置结束:

开始位置:线程id(从0开始) * 每条线程下载的数据长度

结束位置:(线程id + 1) * 每条线程下载的数据长度- 1

③、使用HTTP的请求头字段Range指定每条线程从文件的什么位置开始下载,到什么位置下载结束。

例如指定从文件的2M位置开始下载,下载到位置(4M-1byte)结束:

[java]view plaincopy

1.HttpURLConnection.setRequestProperty("Range", "bytes=2097152-4194303");

④、保存文件。使用RandomAccessFile类指定每条线程从本地文件的什么位置开始写入数据。

[java]view plaincopy

1.RandomAccessFile threadfile = new RandomAccessFile("QQ2011.exe", "rwd");

2.//指定从文件的什么位置开始写入数据

3.threadfile.seek(2097152);

⑤示例

[java]view plaincopy

1./**

2. * 多线程下载

3. * 从路径中获取文件名称

4. * @param path 下载路径

5. * @return

6. */

7.public static String getFilename(String path){

8.return path.substring(https://www.360docs.net/doc/235594584.html,stIndexOf('/') + 1);

9.}

10./**

11. * 多线程下载

12. * 下载文件

13. * @param path 下载路径

14. * @param threadNum 线程数

15. */

16.public void download(String path, int threadNum) throws Exception{

17. URL url = new URL(path);

18. HttpURLConnection conn = (HttpURLConnection)url.openConnection();

19. conn.setRequestMethod("GET");

20. conn.setConnectTimeout(5 * 1000);

21.//获取要下载文件的长度

22.int filelength = conn.getContentLength();

23.//从路径中获取文件名称

24. String filename = getFilename(path);

25. File saveFile = new File(filename);

26. RandomAccessFile accessFile = new RandomAccessFile(saveFile, "rwd");

27.//设置本地文件的长度和下载文件长度相同

28. accessFile.setLength(filelength);

29. accessFile.close();

30.//计算每条线程下载的数据长度

31.int block = filelength % threadNum == 0 ? filelength / threadNum : fileleng

th / threadNum + 1;

32.for(int threadid = 0 ; threadid < threadNum ; threadid++){

33.new DownloadThread(url, saveFile, block, threadid).start();

34. }

35.}

37./**

38. * 多线程下载

39. * 下载线程

40. */

41.private final class DownloadThread extends Thread{

42.private URL url;//下载文件的url

43.private File saveFile;//本地文件

44.private int block;//每条线程下载的数据长度

45.private int threadid;//线程id

46.

47.public DownloadThread(URL url, File saveFile, int block, int threadid) {

48.this.url = url;

49.this.saveFile = saveFile;

50.this.block = block;

51.this.threadid = threadid;

52. }

53.

54.@Override

55.public void run() {

56.//计算开始位置公式:线程id * 每条线程下载的数据长度

57.//计算结束位置公式:(线程id + 1)* 每条线程下载的数据长度 - 1

58.int startposition = threadid * block;

59.int endposition = (threadid + 1 ) * block - 1;

60.try {

61. RandomAccessFile accessFile = new RandomAccessFile(saveFile, "rwd");

62.//设置从什么位置开始写入数据

63. accessFile.seek(startposition);

64. HttpURLConnection conn = (HttpURLConnection)url.openConnection();

65. conn.setRequestMethod("GET");

66. conn.setConnectTimeout(5 * 1000);

67. conn.setRequestProperty("Range", "bytes=" + startposition + "-" + endposi

tion);

68. InputStream inStream = conn.getInputStream();

69.byte[] buffer = new byte[1024];

70.int len = 0;

71.while( (len = inStream.read(buffer)) != -1 ){

72. accessFile.write(buffer, 0, len);

73. }

74. inStream.close();

75. accessFile.close();

76. System.out.println("线程id:" + threadid + " 下载完成");

77. } catch (Exception e) {

78. e.printStackTrace();

android本地文件读取和保存字符串

android将数据存储到文件和从文件中读取字符串 1.读取数据(filename是读取文件的名称,reads是返回读取的字符串) private String readFile(String filename) { try { FileInputStream fis = this.openFileInput(filename); byte[] b = new byte[1024]; ByteArrayOutputStream baos = new ByteArrayOutputStream(); while (fis.read(b) != -1) { baos.write(b, 0, b.length); } baos.close(); fis.close(); reads = baos.toString(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return reads; } 2.写入保存(str是要存入的字符串,filename是保存文件的名称) private void saveFile(String str, String filename) { FileOutputStream fos; try { fos = this.openFileOutput(filename, Activity.MODE_PRIVATE); fos.write(str.getBytes()); fos.flush(); fos.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace();

android系统开机启动流程分析

一,系统引导bootloader 加电,cpu执行bootloader程序,正常启动系统,加载boot.img【其中包含内核。还有ramdisk】 二,内核kernel bootloader加载kernel,kernel自解压,初始化,载入built-in驱动程序,完成启动。 内核启动后会创建若干内核线程,在后装入并执行程序/sbin/init/,载入init process,切换至用户空间(user-space) 内核zImage解压缩 head.S【这是ARM-Linux运行的第一个文件,这些代码是一个比较独立的代码包裹器。其作用就是解压Linux内核,并将PC指针跳到内核(vmlinux)的第一条指令】首先初始化自解压相关环境(内存等),调用decompress_kernel进行解压,解压后调用start_kernel启动内核【start_kernel是任何版本linux内核的通用初始化函数,它会初始化很多东西,输出linux版本信息,设置体系结构相关的环境,页表结构初始化,设置系 统自陷入口,初始化系统IRQ,初始化核心调度器等等】,最后调用rest_init【rest_init 会调用kernel_init启动init进程(缺省是/init)。然后执行schedule开始任务调度。这个init是由android的./system/core/init下的代码编译出来的,由此进入了android的代码】。 三,Init进程启动 【init是kernel启动的第一个进程,init启动以后,整个android系统就起来了】 init进程启动后,根据init.rc 和init. .rc脚本文件建立几个基本 服务(servicemanager zygote),然后担当property service 的功能 打开.rc文件,解析文件内容。【system/core/init/init.c】将service信息放置到service.list中【system/core/init/init_parser.c】。 建立service进程。【service_start(…) execve(…)】 在init.c中,完成以下工作 1、初始化log系统【解析/init.rc和init.%hardware%.rc文件,在两个 文件解析步骤2时执行“early-init”行动】 2、初始化设备【在/dev下创建所有设备节点,下载firmwares】 3、初始化属性服务器【在两个文件解析步骤2时执行“init”行动】

Android系统架构详解

Android系统架构详解 Android系统架构由5部分组成, 分别是:Linux Kernel、Android Runtime、Libraries、Application Framework、Applications。 1、Linux Kernel Android relies on Linux version 2.6 for core system services such as security, memory management, process management, network stack, and driver model. The kernel also acts as an abstraction layer between the hardware and the rest of the software stack. Android基于Linux 2.6提供核心系统服务,例如:安全、内存管理、进程管理、网络堆栈、驱动模型。Linux Kernel也作为硬件和软件之间的抽象层,它隐藏具体硬件细节而为上层提供统一的服务。如果你学过计算机网络知道OSI/RM,就会知道分层的好处就是使用下层提供的服务而为上层提供统一的服务,屏蔽本层及以下层的差异,当本层及以下层发生了变化不会影响到上层。也就是说各层各尽其职,各层提供固定的SAP(Service Access Point),专业点可以说是高内聚、低耦合。如果你只是做应用开发,就不需要深入了解Linux Kernel层。 2、Android Runtime Android includes a set of core libraries that provides most of the functionality available in the core libraries of the Java programming language. Android包括一个核心库的集合,她们提供了Java编程语言的核心库中的绝大多数功能。 Every Android application runs in its own process, with its own instance of the Dalvik virtual

Android学习笔记---SQLite介绍,以及使用Sqlite,进行数据库的创建,完成数据添删改查的理解

Android学习笔记---SQLite介绍,以及使用Sqlite,进行数据库的创建,完成数据添删改查的理解 17_创建数据库与完成数据添删改查--------------------------------------1.SQLite介绍:最大特点是,无数据类型; 除了可以使用文件或SharedPreferences存储数据,还可以选择使用SQLite数据库存储数据。在Android平台上,集成了一个嵌入式关系型数据库—SQLite,SQLite3支持 NULL、INTEGER n n 、REAL(浮点数字)、TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型 n n 只有五种,但实际上sqlite3也接受varchar(n)、char(n)、decimal(p,s) 等数据类型,只不 n n 过在运算或保存时会转成对应的五种数据类型。 SQLite最大的特点是你可以把各种类型的数n n 据保存到任何字段中,而不用关心字段声明的数据类型是什么。例如:可以在Integer类型的 n n 字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值。n n n 但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数, 当向这种字段 n n 保存除整数以外的数据时,将会产生错误。 另外, SQLite 在解析CREATE TABLE 语句时, n n 会忽略 CREATE TABLE 语句中跟在字段名后面的数据类型信息,如下面语句会忽略 name字段 n n 的类型信息: CREATE TABLE person (personid integer primary key autoincrement, name varchar n n (20)) SQLite可以解析大部分标准SQL语句,如:查询语句:select * from 表名 where 条件子句 group by 分组字句 having ... order byn n n 排序子句如:select * from person n n n n select * from person order by id desc n n n n select name from person group by name having count(*)>1 ---------------------------------------------------------------------------2.a.分页SQL与mysql类似,下面SQL语句获取5条记录,跳过前面3条记录n n select * from Account limit 5 offset 3 或者 select * from Account limit 3,5 n b.select * from Account limit 3,5,指的是跳过前面的3条记录,然后获取5条记录n c.select * from Account limit 3,5是select * from Account limit 5 offset 3语句 n n 的简写版 -------------------------------------------------------------------------------n 3.常用操作: a.插入语句:insert into 表名(字段列表) values(值列表)。如: insert into person nn n n (name, age) values(‘传智’,3) b.更新语句:update 表名 set 字段名=值where 条件子句。如:update person set name=n n n n'credream ‘where id=10 c.删除语句:delete from 表名 where 条件子句。如:delete from person nwhere id=10 -------------------------------------------------------------------------------2.虽然无数据类型,但是建议加上,这样可以增加可读性,支持标准sql,oracle中的不行 ---------------------------------------------------3.获取添加记录后的自增长的ID值:select last_insert_rowid(); -----------------------------------------------------------4.在android中开发数据库应用: n a.创建数据库:以前在javaee时候,需要手工数据,但是android应用,需要运行在用户的 n n 手机上,所以,android应用,要有自动创建数据库功能,当第一次使用软件的时候 n n 就创建数据库----------------------------------------5.关于数据库自动创建的详细介绍: 我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很 n n 多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用软件时创建出 n n 应用使用到的数据库表结构及添加一些初始化记录,另外在软件升级的时候,也需要对数据 n n 表结构进行更新。那么,我们如何才能实现在用户初次使用或升级软件时自动在用户的手机 n n 上创建出应用需要的数据库表呢?总不能让我们在每个需要安装此软件的手机上通过手工方 n n 式创建数据库表吧?因为这种需求是每个数据库应用都要面临的,所以在Android系统,为我 n n 们提供了一个名为SQLiteOpenHelper的抽象类,必须继承它才能使用,它是通过对数据库版 n n 本进行管理来实现前面提出的需求。n -----------------------------------------6.SQLite数据库添加,删除,改查操作 n A.创建数据库:SQLiteOpenHelper .getWritableDatabase ()或getReadableDatabase() n n 可以创建数据库7.创建完成以后可以使用SQLITE Expert软件打开生成的数据库n 可以看到除了生成的自己的需要的表之外,还生成了一张:android_metadata表: n 如果在sqlite中使用数据库一定会有一张android_metadata表,用来登记用户的 n 使用语言:zh_cn -----------------------------------------------------n b.数据库自动创建的过程及方法详细介绍: n n我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在 n n 很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用软件时创建 n n 出应用使用到的数据库表结构及添加一些初始化记录,另外在软件升级的时候,也需要对数n n 据表结构进行更新。那么,我们如何才能实现在用户初次使用或升级软件时自动在用户的手 n n 机上创建出应用需要的数据库表呢?总不能让我们在每个需要安装此软件的手机上通过手工 n n 方式创建数据库表吧?因为这种需求是每个数据库应用都要面临的,所以在Android系统,为n n 我们提供了一个名为SQLiteOpenHelper的抽象类,必须继承它才能使用,它是通过对数据库n n 版本进行管理来实现前面提出的需求。n -------------------------------------------8.详细介绍: 为了实现对数据库版本进行管理,SQLiteOpenHelper类提供了两个重要的方法,分别是 n n onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db, int oldVersion, intn n n newVersion),前者用于初次使用软件时生成数据库表,后者用于升级软件时更新数据库表结n n 构。当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法获n n 取用于操作数据库的SQLiteDatabase实例的时候,如果数据库不存在,Android系统会自动生 n n 成一个数据库,接着调用onCreate()方法,onCreate()方法在初次生成数据库时才会被调用 n n ,在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始化数据。 n n onUpgrade()方法在数据库的版本发生变化时会被调用,一般在软件升级时才需改变版本号, n n 而数据库的版本是由程序员控制的,假设数据库现在的版本是1,由于业务的变更,修改了数n n 据库表结构,这时候就需要升级软件,升级软件时希望更新用户手机里的数据库表结构,为n n 了实现这一目的,可以把原来的数据库版本设置为2(有同学问设置为3行不行?当然可以,如 n n 果你愿意,设置为100也行),并且在onUpgrade()方法里面实现表结构的更新。当软件的版本 n n 升级次数比较多,这时在onUpgrade()方法里面可以根据原版号和目标版本号进行判断,然后 n n 作出相应的表结构及数据更新。 getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的 n n SQLiteDatabase实例。但getWritableDatabase() 方法以读写方式打开数据库,一旦数据库n n 的磁盘空间满了,数据库就只能读而不能写,倘若使用的是getWritableDatabase() 方法就 n n 会出错。getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了 n n ,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。 ------------------------------------------------------------------------9.创建数据库的代码: n a.创建项目:DBSQLIte n b./DBSQLIte/src/com/credream/service/DBOpenHelter.java n n package com.credream.service; n n import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteDatabase.CursorFactory; n n public class DBOpenHelter extends SQLiteOpenHelper { //父类没有默认构造器,需要显示调用 public DBOpenHelter(Context context) { super (context, "credream.db", null, 1); //数据库创建完成后,默认会保存在<包>/database/文件夹下 //当修改版本号时候,会触发:onUpgrade方法 //第二个:指定数据库名称, //第三个:游标工厂,用来迭代,查询后的结果集,null代表使用系统默认的 n n 游标工厂//版本号,大于0 n } /** n* 这个方法是在数据库第一次被创建的时候调用的 n*/ @Override public void onCreate(SQLiteDatabase db) { //SQLiteDatabase这个类,封装了增删改查操作,也叫做数据库操作实例 db.execSQL("CREATE TABLE person (personid integer primary keyn n n autoincrement, name varchar(20))"); //这里也可以不写name的数据类型,因为sqlite是数据类型无关的,就是写n n 了varchar(20),也可以写入超过20的内容 n n } /** n* 当数据库的版本号变更的时候被调用 n*/ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("alter table person add phone varchar(12) null"); n n } n n } --------------------------------------------------------2.在清单文件中写入测试环境 n n n n n n n n n n ---------------------------------------------------- 3./DBSQLIte/src/com/credream/test/PersonServiceTest.java package com.credream.test; n n import com.credream.service.DBOpenHelter; n n import android.test.AndroidTestCase; n n public class PersonServiceTest extends AndroidTestCase { //创建数据库,在<包>/database/ public void testCreateDB(){ DBOpenHelter dbOpenHelter=new DBOpenHelter(getContext()); dbOpenHelter.getWritableDatabase(); n } n n } -------------------------------------------------------4.选择方法开始测试,然后,在data/data/<包>/database/下 n 查看并用sqlite打开生成的数据库检查是否正确---------------------------------------------然后将版本号,改成2,然后再次执行,看到,表已经被更新,增加了一列phone -----------------------------------------------5.了解sqlite工作的原理: n DBOpenHelter dbOpenHelter=new DBOpenHelter(getContext()); dbOpenHelter.getWritableDatabase(); n 打开getWritableDatabase();代码:

计科1141班胡志泉安卓实验6 - 数据存储与访问

GDOU-B-11-112广东海洋大学学生实验报告书(学生用表)实验名称实验6:数据存储与访问课程名称移动编程课程号16242215x0学院(系) 数学与计算机专业计算机科学与技术班级计科1141班学生姓名学号实验地点科技楼425 实验日期2017.4.1 一、实验目的 1.熟悉在Android Studio开发环境下编写Android应用程序的流程; 2.理解在Android Studio开发环境下进行用户界面设计的基本方法; 3.掌握应用Android碎片控件Fragment开发适用于大屏幕的应用程序的方法。 4.掌握应用Android存储方法SharePreferences的应用方法。 二、实验内容 在Android Studio开发环境下,使用Android的Fragment碎片控件、TextView文本标签控件、ListView列表控件、FrameLayout框架布局控件,利用SharePreferences存储方法,采用双页显示模式实现一个适用于大屏幕设备的简易新闻阅读器应用程序。 三、实验设备 Android Studio 四、实验结果 用户界面布局设计采用了水平线性布局方式,分为左右两个碎片Fragment;其中,左侧为新闻标题列表子界面,右侧为新闻详细内容子界面。当点击新闻标题列表中的某一标题时,右侧的Fragment将显示相应新闻标题的详细内容。

五、源代码 主Activity的布局文件activity_main.xml的源代码

Android 开机启动流程

Android的开机流程 1. 系统引导bootloader 1) 源码:bootable/bootloader/* 2) 说明:加电后,CPU将先执行bootloader程序,此处有三种选择 a) 开机按Camera+Power启动到fastboot,即命令或SD卡烧写模式,不加载内核及文件系统,此处可以进行工厂模式的烧写 b) 开机按Home+Power启动到recovery模式,加载recovery.img,recovery.i mg包含内核,基本的文件系统,用于工程模式的烧写 c) 开机按Power,正常启动系统,加载boot.img,boot.img包含内核,基本文件系统,用于正常启动手机(以下只分析正常启动的情况) 2. 内核kernel 1) 源码:kernel/* 2) 说明:kernel由bootloader加载 3. 文件系统及应用init 1) 源码:system/core/init/* 2) 配置文件:system/rootdir/init.rc, 3) 说明:init是一个由内核启动的用户级进程,它按照init.rc中的设置执行:启动服务(这里的服务指linux底层服务,如adbd提供adb支持,vold提供SD卡挂载等),执行命令和按其中的配置语句执行相应功能 4. 重要的后台程序zygote 1)源码:frameworks/base/cmds/app_main.cpp等 2) 说明:zygote是一个在init.rc中被指定启动的服务,该服务对应的命令是/system/bin/app_process a)建立Java Runtime,建立虚拟机 b) 建立Socket接收ActivityManangerService的请求,用于Fork应用程序 c) 启动System Server 5. 系统服务system server 1)源码:frameworks/base/services/java/com/android/server/SystemServer.jav a 2) 说明:被zygote启动,通过SystemManager管理android的服务(这里的服务指frameworks/base/services下的服务,如卫星定位服务,剪切板服务等) 6. 桌面launcher 1)源码:ActivityManagerService.java为入口,packages/apps/launcher*实现 2) 说明:系统启动成功后SystemServer使用xxx.systemReady()通知各个服务,系统已经就绪,桌面程序Home就是在ActivityManagerService.systemReady()通知的过程中建立的,最终调用()启launcher 7. 解锁 1) 源码: frameworks/policies/base/phone/com/android/internal/policy/impl/*lock* 2) 说明:系统启动成功后SystemServer调用wm.systemReady()通知WindowManagerService,进而调用PhoneWindowManager,最终通过LockPatternKeyguardView显示解锁界面,跟踪代码可以看到解锁界面并不是一个Activity,这是只是向特定层上绘图,其代码了存放在特殊的位置

Android系统架构简介

Android系统架构简介 Android系统架构简介 目前Android的Linuxkernel控制包括安全、存储器管理、进程管理、网络堆叠、驱动程序模型等。下载Android源码之前,先要 安装其构建工具Repo来初始化源码。Repo是Android用来辅助Git 工作的一个工具。 应用程序 Android系统是基于Linux内核开发,使用Java作编程语言, 使界面到功能,都有层出不穷的变化,其中Activity等同于J2ME 的MIDlet,一个Activity类别负责创建视窗,一个活动中的 Activity就是在foreground(前景)模式,背景执行的程序叫做Service。两者之间透过由ServiceConnection和AIDL连结,达到 复数程序同时执行的效果。如果执行中的Activity全部画面被其他Activity取代时,该Activity便被停止,甚至被系统清除。 View等同于J2ME的Displayable,程序人员可以透过View类别与“XMLlayout”档将UI放置在视窗上,并可以利用View打造出所 谓的Widgets,其实Widget只是View的一种,所以可以使用xml 来设计layout。至于ViewGroup是各种layout的基础抽象类别,ViewGroup之内还可以有ViewGroup。View的构造函数不需要在Activity中调用,但是Displayable的是必须的,在Activity中,要通过findViewById()来从XML中获取View,Android的View类 的显示很大程度上是从XML中读取的。View与事件息息相关,两者 之间透过Listener结合在一起,每一个View都可以注册eventlistener,例如:当View要处理用户触碰的事件时,就要向Android框架注册View.OnClickListener。另外还有Image等同于 J2ME的BitMap。 中介软件

Android移动应用开发实验指导书

《Android移动应用开发》 实验指导书 课程代码: 总课时数: 适用专业: 院(系)名称:

实验一深入理解Activity 目标 (1)掌握Activity的开发、配置和使用。 (2)掌握Intent的几种常用的属性。 (3)Android系统内置Intent的使用。 (4)了解Activity的生命周期 实验软、硬件环境 硬件:PC电脑一台; 配置:winxp或win7系统,内存大于4G,硬盘250G及以上 JDK1.7 、Eclipse、ADT、Android SDK 实验主要技术基础 (1)活动是Android的四大组件之一,它是一种可以包含用户界面的组件,主要用于和用户进行交互。 (2)Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。 任务 1、请在AndroidManifest.xml文件中配置SecondActivity: 配置Intent的Action属性为com.sise.intent.action.JHY_ACTION; 配置Category属性为com.sise.intent.category.JHY_CATEGORY。 通过隐式Intent的使用从FirstActivity启动SecondActivity,编写代码,运行程序,预期效果如下所示。

图1 程序运行初始化界面图2 点击图1中的按钮后的运行结果 2、请使用显式Intent启动SecondActivity,并使用Intent从FirstActiv传递数据到SecondActivity。编写代码,运行程序,预期效果如下所示。 图1 程序运行初始化界面图2 点击图1中的按钮后的运行结果 3、使用Intent传递数据从SecondActivity返回数据到FirstActivity中去。编写代码,运行程序,预期效果如下所示。 图1 程序运行初始化界面图2 点击图1按钮运行结果 图3 点击图2按钮运行结果 实验方法与步骤 (1)创建活动 Activity是Android系统提供的一个活动基类所有的活动都必须直接或间接继承此类才能拥有活动的特性。 (2)布局文件 创建布局文件 加载布局文件 (3)在清单文件中注册活动 (4)以上方法完成多个活动的创建 (5)使用Intent完成多个活动之间的交互和数据传递

linux内核启动 Android系统启动过程详解

linux内核启动+Android系统启动过程详解 第一部分:汇编部分 Linux启动之 linux-rk3288-tchip/kernel/arch/arm/boot/compressed/ head.S分析这段代码是linux boot后执行的第一个程序,完成的主要工作是解压内核,然后跳转到相关执行地址。这部分代码在做驱动开发时不需要改动,但分析其执行流程对是理解android的第一步 开头有一段宏定义这是gnu arm汇编的宏定义。关于GUN 的汇编和其他编译器,在指令语法上有很大差别,具体可查询相关GUN汇编语法了解 另外此段代码必须不能包括重定位部分。因为这时一开始必须要立即运行的。所谓重定位,比如当编译时某个文件用到外部符号是用动态链接库的方式,那么该文件生成的目标文件将包含重定位信息,在加载时需要重定位该符号,否则执行时将因找不到地址而出错 #ifdef DEBUG//开始是调试用,主要是一些打印输出函数,不用关心 #if defined(CONFIG_DEBUG_ICEDCC)

……具体代码略 #endif 宏定义结束之后定义了一个段, .section ".start", #alloc, #execinstr 这个段的段名是 .start,#alloc表示Section contains allocated data, #execinstr表示Section contains executable instructions. 生成最终映像时,这段代码会放在最开头 .align start: .type start,#function /*.type指定start这个符号是函数类型*/ .rept 8 mov r0, r0 //将此命令重复8次,相当于nop,这里是为中断向量保存空间 .endr b 1f .word 0x016f2818 @ Magic numbers to help the loader

Android体系结构

Android体系结构 android 平台大的方面的层次可以划分成三个层次,包括一个操作系统,中间件与应用程序,android 的系统框架图如下: 图中的软件层次自上而下分成4个层次 1. 应用程序(Application) 2. 用用程序框架(Application Framework) 3. 各种类库(Libraries)与android运行时(Adnorid Runtime) 4. 操作系统(OS) 一、应用程序(Application) 应用层就是与用户交互的一个层次,用户可以瞧得见的一些应用,用户可以操作。这类应用基本都就是通过Java语言编写的独立的能够完成某些功能的应用程序。Android本身提供了桌面(Home),联系人(Contacts),拨打电话(Phone),浏览器(Browers)等很多基本的应用程序。开发人员可以使用应用框架提供的API编写自己的应用程序,普通开发人员要做的事情就就是开应用层的程序提供该广大消费者使用。 二、应用程序框架(Application Framework) 普通开发者可以使用Android基本应用程序使用的系统API,android 应用框架中的各个模块都可以被复用,各种服务也可以被复用,理解了这个机制,开发人员可以更好的更轻松的开发出优秀的android应用。 开发过程中常用到的基本框架组件如下:

1. 一组View(UI 组件),这些UI组件包括Button(按钮),EidtView(文本框),TextView(标签),List(列表) 等等,灵活运用这些组件可以快速方便的创建良好的用户交互界面。 2. Content Providers(内容提供者),听起来有点抽象,通俗的理解Content Provider 就就是提供一种 服务,通过这种服务应用程序之间可以实现数据的互相访问与共享,比如通讯录的存储就使用了这种服务,其它应用也可以访问通讯录中存储的联系人信息。 3. Resource Manager 顾名思义就就是资源管理,android中的资源很多包括图片,用户界面(Layout xml),字体,颜色,UI组件的Id等等都可以称之为资源,这些丰富的资源,都就是通过Resource Manager来统一进行管理。 4. Notification Manager(消息通知管理),它在不影响用户正常操作与使用设备的时候在状态栏上提供 消息的提示。比如有短信来的时候,android自动会将这个消息提示在状态栏上,用户可以及时的瞧到。 5. Activity Manager(活动管理),Activity管理着应用程序的生命周期,并且控制着应用的导航,扮演控 制器的角色。每个Activity类似于Windows应用中的一个wendow。一般的应用都就是通过一个个Activity 交互构成的。 6. Window Manager(窗口管理),管理所有启动的窗口。 7. Location Manager(位置管理),用来管理地图服务的相关功能。 8. Telephoney Manager(电话管理),用来管理有关的电话的相关功能。 9. Package Manager(包管理),管理所有的安装在android系统内的应用程序。 三、库(Libraries)与运行环境(RunTime) 这部分内容开始涉及底层,开发普通的应用不会直接对这个层进行操作。这层中包含了一组类库(Libraries)与运行时(RunTime), 1. 系统C库(libc),一个从BSD集成来的标准C系统函数库(libc)它就是专门为基于嵌入式Linux的设 备定制的。 2. 媒体库(Media Framework),基于PackeVideo OpenCore,该库支持多种常用的音频,视频格式以及 回放与录制,同时支持静态图像文件。编码格式包括:MPEG4、H、264,MP3、AAC、AMR、JPG、PNG。 3. Surface Manager 对显示子系统的管理,并且为多个应用提供2D,3D图层的无缝融合。 4. WebKit,一个最新的web浏览器引擎,用来支持Andiroid浏览器或者嵌入的web视图。 5. SGL 底层的2D图形引擎。 6. OPENGL|ES,基于OpenGL ES 1、0 APIs实现,该库可以使用硬件3D加速或者使用高度优化的 3D软加速。 7. FreeType,位图(bitmap)与适量(vector)字图显示支持。 8. SQLite,一个对所有应用程序可用,功能强大的轻量级关系型数据库引擎。 9. Core Libraries 该核心库提供了Java编程语言核心库的大多数功能。 10. Dalvik VM, android平台的一个虚拟机,它相当于PC中Java的虚拟机JVM。 四、操作系统(OS) Android 的核心系统服务依赖于Linux 2、6 内核,操作系统为Android提供的服务包括: 1. 安全性(Security)。 2. 内存管理(Memory Management) 3. 进程管理(Process Management) 4. 网络堆栈(Network Stack) 5. 驱动程序模型(Driver Model)包含以下这些常规的驱动程序: (1)Display Driver (2)Keypad Driver

Android数据存储和数据访问

南昌航空大学实验报告 二0一4 年11 月14 日 课程名称:Android 实验名称:Android数据存储和数据访问 班级:姓名:同组人: 指导教师评定:签名: 一:实验目的 掌握SharedPreferences的使用方法; 掌握各种文件存储的区别与适用情况; 了解SQLite数据库的特点和体系结构; 掌握SQLite数据库的建立和操作方法; 理解ContentProvider的用途和原理; 掌握ContentProvider的创建与使用方法 二:实验工具 Eclipse(MyEclipse)+ ADT + Android2.2 SDK; 三:实验题目 1.应用程序一般允许用户自己定义配置信息,如界面背景颜色、字体大小和字体颜色等,尝试使用SharedPreferences保存用户的自定义配置信息,并在程序启动时自动加载这些自定义的配置信息。 2.尝试把第1题的用户自己定义配置信息,以INI文件的形式保存在内部存储器上。 3.使用代码建库的方式,创建名为test.db的数据库,并建立staff数据表,表内的属性值如下表所示:

4.建立一个ContentProvider,用来共享第3题所建立的数据库; 四:实验代码 Internal public class Internal extends Activity { private final String = ""; private TextView labelView; private TextView displayView; private CheckBox appendBox ; private EditText entryText; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(https://www.360docs.net/doc/235594584.html,yout.main); labelView = (TextView)findViewById(https://www.360docs.net/doc/235594584.html,bel); displayView = (TextView)findViewById(R.id.display); appendBox = (CheckBox)findViewById(R.id.append); entryText = (EditText)findViewById(R.id.entry); Button writeButton = (Button)findViewById(R.id.write); Button readButton = (Button)findViewById(R.id.read); writeButton.setOnClickListener(writeButtonListener); readButton.setOnClickListener(readButtonListener); entryText.selectAll(); entryText.findFocus(); } OnClickListener writeButtonListener = new OnClickListener() { @Override public void onClick(View v) {

相关文档
最新文档