java攻城狮之路(Android篇)--与服务器交互
一、图片查看器和网页源码查看器
在输入地址的是不能输入127.0.0.1 或者是 localhost.
ScrollView :可以看成一个滚轴 可以去包裹很多的控件在里面
练习1(图片查看器):
package com.shellway.imagelooker; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import org.apache.http.conn.ConnectTimeoutException; import android.support.v7.app.ActionBarActivity; import android.annotation.SuppressLint; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.StrictMode; import android.view.View; import android.widget.EditText; import android.widget.ImageView; import android.widget.Toast; public class MainActivity extends ActionBarActivity { private EditText path; private ImageView iv; @SuppressLint("NewApi") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); path = (EditText) findViewById(R.id.et_path); iv = (ImageView) findViewById(R.id.iv_image); StrictMode.ThreadPolicy policy=new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); } public void onLook(View view){ String spath = path.getText().toString(); System.out.println(spath); if(spath.equals("")){ Toast.makeText(this, "输入的地址为空", Toast.LENGTH_SHORT).show(); }else { try { URL url = new URL(spath); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); if(conn.getResponseCode() == 200){ InputStream is = conn.getInputStream(); Bitmap bm = BitmapFactory.decodeStream(is); if(bm == null){ Toast.makeText(this, "获取的图片流为空", Toast.LENGTH_SHORT).show(); }else{ iv.setImageBitmap(bm); } }else{ Toast.makeText(this, "输入的路径不存在", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { e.printStackTrace(); if(e instanceof MalformedURLException){ Toast.makeText(this, "输入的路径格式错误", Toast.LENGTH_SHORT).show(); }else if(e instanceof ConnectTimeoutException){ Toast.makeText(this, "连接超时错误", Toast.LENGTH_SHORT).show(); }else if(e instanceof IOException){ Toast.makeText(this, "获取数据错误", Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(this, "未知错误", Toast.LENGTH_SHORT).show(); } } } } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.shellway.imagelooker" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
练习2(网页源码查看器):
package com.shellway.htmllooker; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import org.apache.http.client.utils.URIUtils; import android.support.v7.app.ActionBarActivity; import android.text.TextUtils; import android.annotation.SuppressLint; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.StrictMode; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.webkit.URLUtil; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends ActionBarActivity { protected static final int CHANGE_UI = 1; private EditText et_path; private TextView iv; private String path; // private Handler handler; @SuppressLint("NewApi") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_path = (EditText) findViewById(R.id.et_path); iv = (TextView) findViewById(R.id.iv_image); /* handler = new Handler(){ public void handleMessage(Message msg) { if(msg.what == CHANGE_UI){ String s = (String) msg.obj; iv.setText(s); } }; };*/ StrictMode.ThreadPolicy policy=new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); } public void onLook(View view){ path = et_path.getText().toString().trim(); if(TextUtils.isEmpty(path)){ Toast.makeText(MainActivity.this, "您输入的地址为空", Toast.LENGTH_SHORT).show(); }else{ // new Thread(){ // public void run() { try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); if(conn.getResponseCode()==200){ InputStream is = conn.getInputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len=0 ; while((len = is.read(buffer))!=-1){ bos.write(buffer, 0, len); } String text =bos.toString(); bos.close(); is.close(); // Message msg = new Message(); // msg.what = CHANGE_UI; // msg.obj = text; // handler.sendMessage(msg); iv.setText(text); } } catch (Exception e) { e.printStackTrace(); } // }; // }.start(); } } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.shellway.htmllooker" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
二、网易新闻客户端
1.对抓取的数据进行一个描述,我们用的是xml文件来进行描述,如:
<HeaderNews>
<HeaderNew>
<image>httP://192.168.1.101:8080/web/a.jpg<image>
<title>女子花3万相亲</title>
<content>婚介所向其介绍男友后消失<content>
<count>44跟帖</count>
</HeaderNew>
</HeaderNews>
首先数据是动态的。我们可以用servlet(查询数据库里面的数据) - 然后传递数据通过request(转发)--> jsp 显示
findViewById() 直接使用是在我们的activity的布局里面去查找
注意:流被使用过之后,就不能再次使用。
练习:
首先,模拟一个服务器(创建web工程):
<?xml version="1.0" encoding="utf-8"?> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <HeaderNews> <c:forEach items="${headerNews}" var="headernew"> <HeaderNew> <image>${headernew.image}</image> <title>${headernew.title}</title> <content>${headernew.content}</content> <count>${headernew.count}</count> </HeaderNew> </c:forEach> </HeaderNews>
package com.shellway.news.domain; public class HeaderNew { private String image; private String title; private String content; private String count; public HeaderNew() { super(); } public HeaderNew(String image, String title, String content, String count) { super(); this.image = image; this.title = title; this.content = content; this.count = count; } public String getImage() { return image; } public void setImage(String image) { this.image = image; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getCount() { return count; } public void setCount(String count) { this.count = count; } @Override public String toString() { return "HeaderNew [image=" + image + ", title=" + title + ", content=" + content + ", count=" + count + "]"; } }
package com.shellway.news.service; import java.util.ArrayList; import java.util.List; import com.shellway.news.domain.HeaderNew; public class HeaderNewsService { private List<HeaderNew> HeaderNews = new ArrayList<HeaderNew>(); public List<HeaderNew> getHeaderNews(){ HeaderNews.add(new HeaderNew("http://192.168.1.101:80/web/a.jpg","女子花3万相亲","婚介所向其介绍男友1后消失","44跟帖")); HeaderNews.add(new HeaderNew("http://192.168.1.101:80/web/b.jpg","女子花4万相亲","婚介所向其介绍男友2后消失","12跟帖")); HeaderNews.add(new HeaderNew("http://192.168.1.101:80/web/c.jpg","女子花5万相亲","婚介所向其介绍男友3后消失","22跟帖")); HeaderNews.add(new HeaderNew("http://192.168.1.101:80/web/d.jpg","女子花6万相亲","婚介所向其介绍男友4后消失","32跟帖")); HeaderNews.add(new HeaderNew("http://192.168.1.101:80/web/e.jpg","女子花7万相亲","婚介所向其介绍男友5后消失","24跟帖")); HeaderNews.add(new HeaderNew("http://192.168.1.101:80/web/a.jpg","女子花8万相亲","婚介所向其介绍男友6后消失","15跟帖")); return HeaderNews; } }
package com.shellway.news.servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.catalina.connector.Request; import com.shellway.news.domain.HeaderNew; import com.shellway.news.service.HeaderNewsService; public class HeaderNewsServlet extends HttpServlet { private static final long serialVersionUID = 1L; public HeaderNewsServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HeaderNewsService service = new HeaderNewsService(); List<HeaderNew> HeaderNews = service.getHeaderNews(); request.setAttribute("headerNews", HeaderNews); request.getRequestDispatcher("/WEB-INF/page/headernewsxml.jsp").forward(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>web</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <description></description> <display-name>HeaderNewsServlet</display-name> <servlet-name>HeaderNewsServlet</servlet-name> <servlet-class>com.shellway.news.servlet.HeaderNewsServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HeaderNewsServlet</servlet-name> <url-pattern>/HeaderNewsServlet</url-pattern> </servlet-mapping> </web-app>
然后,创建一个Android客户端工程(News)
package com.shellway.news.domain; public class HeaderNew { private String image; private String title; private String content; private String count; public HeaderNew() { super(); } public HeaderNew(String image, String title, String content, String count) { super(); this.image = image; this.title = title; this.content = content; this.count = count; } public String getImage() { return image; } public void setImage(String image) { this.image = image; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getCount() { return count; } public void setCount(String count) { this.count = count; } @Override public String toString() { return "HeaderNew [image=" + image + ", title=" + title + ", content=" + content + ", count=" + count + "]"; } }
package com.shellway.news; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Properties; import org.xmlpull.v1.XmlPullParser; import android.content.Context; import android.os.Environment; import android.util.Xml; import com.shellway.news.domain.HeaderNew; public class HeaderNewsService { //得到所有的头条新闻 public List<HeaderNew> getHeaderNews(Context context) throws Exception{ String path = context.getResources().getString(R.string.serverurl); URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); if(conn.getResponseCode()==200){ InputStream is = conn.getInputStream(); return parserHeaderNews(is); } return null; } //解析流为新闻集合 private List<HeaderNew> parserHeaderNews(InputStream is) throws Exception { List<HeaderNew> headerNews = null; HeaderNew headerNew = null; //1 得到解析器 XmlPullParser parser = Xml.newPullParser(); //设值解析流编码 parser.setInput(is, "utf-8"); //得到解析事件 int eventType = parser.getEventType(); while(eventType!=XmlPullParser.END_DOCUMENT){ switch (eventType) { case XmlPullParser.START_TAG: if("HeaderNews".equals(parser.getName())){ headerNews = new ArrayList<HeaderNew>(); }else if("HeaderNew".equals(parser.getName())){ headerNew = new HeaderNew(); }else if("image".equals(parser.getName())){ headerNew.setImage(parser.nextText()); }else if("title".equals(parser.getName())){ headerNew.setTitle(parser.nextText()); }else if("content".equals(parser.getName())){ headerNew.setContent(parser.nextText()); }else if("count".equals(parser.getName())){ headerNew.setCount(parser.nextText()); } break; case XmlPullParser.END_TAG: if ("HeaderNew".equals(parser.getName())) { headerNews.add(headerNew); headerNew = null; } break; default: break; } eventType = parser.next(); } return headerNews; } //得到文件 public File getImage(String path) throws Exception{ URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); Properties pro = new Properties(); if(conn.getResponseCode()==200){ InputStream is = conn.getInputStream(); //缓存图片 String name = path.substring(path.lastIndexOf("/")+1); File file = new File(Environment.getExternalStorageDirectory(),name); FileOutputStream fos = new FileOutputStream(file); byte[] buffer = new byte[1024]; int len = 0; while ((len = is.read(buffer))!=-1) { fos.write(buffer, 0, len); } fos.close(); return file; } return null; } }
package com.shellway.news; import java.io.File; import java.util.List; import com.shellway.news.domain.HeaderNew; import android.support.v7.app.ActionBarActivity; import android.annotation.SuppressLint; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.StrictMode; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends ActionBarActivity { private ListView lv_news; private HeaderNewsService service; private List<HeaderNew> headernews; private LayoutInflater mInflater; @SuppressLint("NewApi") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); service = new HeaderNewsService(); mInflater = LayoutInflater.from(this); lv_news = (ListView) findViewById(R.id.lv_news); //下面两行是允许在主线程中执行联网这一耗时操作 StrictMode.ThreadPolicy policy=new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); try { headernews = service.getHeaderNews(this); //设值数据 lv_news.setAdapter(new MyBaseAdapter()); } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "获取新闻失败", Toast.LENGTH_SHORT).show(); } } private class MyBaseAdapter extends BaseAdapter{ @Override public int getCount() { return headernews.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { //View item = View.inflate(getApplicationContext(), R.layout.item, null); //加载布局 View item = mInflater.inflate(R.layout.item, null); //得到控件 ImageView iv = (ImageView) item.findViewById(R.id.iv_image); TextView title = (TextView) item.findViewById(R.id.tv_title); TextView content = (TextView) item.findViewById(R.id.tv_content); TextView count = (TextView) item.findViewById(R.id.tv_count); //得到数据 HeaderNew hw = headernews.get(position); //绑定数据 File imagefile; try { //图片是否有缓存 现在图片应该保存sdcard String path = hw.getImage(); String name = path.substring(path.lastIndexOf("/")+1); File file = new File(Environment.getExternalStorageDirectory(),name); if (!file.exists()) { imagefile = service.getImage(hw.getImage()); if(imagefile!=null){ iv.setImageURI(Uri.fromFile(imagefile)); } }else { iv.setImageURI(Uri.fromFile(file)); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } title.setText(hw.getTitle()); content.setText(hw.getContent()); count.setText(hw.getCount()); return item; } } }
package com.shellway.news.test; import java.util.List; import com.shellway.news.HeaderNewsService; import com.shellway.news.domain.HeaderNew; import android.test.AndroidTestCase; import android.util.Log; public class HeaderNewsTest extends AndroidTestCase { public void testGetHeaderNews() throws Exception{ HeaderNewsService service = new HeaderNewsService(); List<HeaderNew> headerNews = service.getHeaderNews(getContext()); for(HeaderNew headerNew:headerNews){ Log.i("i", headerNew.toString()); } } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.shellway.news" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" /> <instrumentation android:targetPackage="com.shellway.news" android:name="android.test.InstrumentationTestRunner" /> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <uses-library android:name="android.test.runner" /> <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ListView android:id="@+id/lv_news" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#EEEDEC" android:layout_margin="5dp" > <ImageView android:id="@+id/iv_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/default1" android:layout_margin="5dp" /> <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/iv_image" android:textSize="22sp" android:textColor="@android:color/black" android:text="小三小四" /> <TextView android:id="@+id/tv_content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_title" android:layout_toRightOf="@id/iv_image" android:textSize="18sp" android:text="小五小六" /> <TextView android:id="@+id/tv_count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_content" android:layout_alignParentRight="true" android:textSize="18sp" android:text="44跟帖" /> </RelativeLayout>
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="serverurl">http://192.168.1.101:80/web/HeaderNewsServlet</string> </resources>
效果图:
方式二:利用json实现数据的获取,json是一个轻量级的数组:
格式:[{image:"httP://192.168.1.101:8080/web/a.jpg",title:"...",content:"...",count:"..."}
服务器端增加一个servlet(HeaderNewsJsonServlet):
package com.shellway.news.servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.shellway.news.domain.HeaderNew; import com.shellway.news.service.HeaderNewsService; public class HeaderNewsJsonServlet extends HttpServlet { private static final long serialVersionUID = 1L; public HeaderNewsJsonServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HeaderNewsService headerNewsService = new HeaderNewsService(); List<HeaderNew> headerNews = headerNewsService.getHeaderNews(); StringBuilder sb = new StringBuilder("["); for (HeaderNew headerNew : headerNews) { sb.append("{"); sb.append("image:").append("\"").append(headerNew.getImage()).append("\"").append(","); sb.append("title:").append("\"").append(headerNew.getTitle()).append("\"").append(","); sb.append("content:").append("\"").append(headerNew.getContent()).append("\"").append(","); sb.append("count:").append("\"").append(headerNew.getCount()).append("\""); sb.append("}"); sb.append(","); } sb.deleteCharAt(sb.length()-1); sb.append("]"); request.setAttribute("json", sb); request.getRequestDispatcher("/WEB-INF/page/headernewsjson.jsp").forward(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
在Android客户断中增加(HeaderNewsJsonService):
package com.shellway.news; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import org.json.JSONArray; import org.json.JSONObject; import android.content.Context; import com.shellway.news.domain.HeaderNew; public class HeaderNewsJsonService { List<HeaderNew> headerNews = new ArrayList<HeaderNew>(); public List<HeaderNew> getHeaderNewsFromJson(Context context) throws Exception{ String path = context.getResources().getString(R.string.serverjsonurl); URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); if(conn.getResponseCode()==200){ InputStream is = conn.getInputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while((len = is.read(buffer)) != -1){ bos.write(buffer, 0, len); } String s = bos.toString(); bos.close(); is.close(); JSONArray jsonArray = new JSONArray(s); for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); HeaderNew headerNew = new HeaderNew(); headerNew.setImage(jsonObject.getString("image")); headerNew.setTitle(jsonObject.getString("title")); headerNew.setContent(jsonObject.getString("content")); headerNew.setCount(jsonObject.getString("count")); headerNews.add(headerNew); } } return headerNews; } }
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="serverurl">http://192.168.1.101:80/web/HeaderNewsServlet</string> <string name="serverjsonurl">http://192.168.1.101:80/web/HeaderNewsJsonServlet</string> </resources>
三、以get请求和以post请求往服务器提交数据,通过httpClient提交数据、服务器端文件上传
1、get请求:(把要提交的数据直接添加到路径的后面)
缺点:由于服务器对请求路径的长度是有限制的。最大不能超过4k,截取数据导致数据不完整。
练习:(以get请求数据提交到服务器,并且实现统一的编码)
服务器端:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>login</title> </head> <body> <form action="http://192.168.1.101:80/LoginForWeb/LoginServlet" method="get"> 用户名 :<input type="text" name="username"><br/> 密 码: <input type="password" name="password"><br/> <input type="submit" value="登录"> </form> </body> </html>
package com.shellway.login.servlet; import java.io.IOException; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; public LoginServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("username"); // String name1 = new String(name.getBytes("iso-8859-1"),"utf-8"); 这一行使用过滤器实现 String password = request.getParameter("password"); System.out.println("name:"+name+", password:"+password); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
package com.shellway.login.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; public class EncodingSerlvetRequestFilter implements Filter { public EncodingSerlvetRequestFilter() { } public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; String method = req.getMethod(); if (method.equals("GET")) { EncodingHttpServletRequestWrapper warpper = new EncodingHttpServletRequestWrapper(req); chain.doFilter(warpper, response); }else{ chain.doFilter(request, response); } } public void init(FilterConfig fConfig) throws ServletException { } }
package com.shellway.login.filter; import java.io.UnsupportedEncodingException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; public class EncodingHttpServletRequestWrapper extends HttpServletRequestWrapper { private HttpServletRequest request; public EncodingHttpServletRequestWrapper(HttpServletRequest request) { super(request); this.request = request; } @Override public String getParameter(String name) { String value = request.getParameter(name); if (value != null) { String nname; try { nname = new String(value.getBytes("iso-8859-1"),"utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); throw new RuntimeException("请输入正确的字符编码集名称"); } return nname; } return super.getParameter(name); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>LoginForWeb</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <description></description> <display-name>LoginServlet</display-name> <servlet-name>LoginServlet</servlet-name> <servlet-class>com.shellway.login.servlet.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/LoginServlet</url-pattern> </servlet-mapping> <filter> <display-name>SerlvetRequestFilter</display-name> <filter-name>SerlvetRequestFilter</filter-name> <filter-class>com.shellway.login.filter.EncodingSerlvetRequestFilter</filter-class> </filter> <filter-mapping> <filter-name>SerlvetRequestFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
Android客户端:
package com.example.login; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import android.support.v7.app.ActionBarActivity; import android.text.TextUtils; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends ActionBarActivity { private EditText et_username; private EditText et_password; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_username = (EditText) findViewById(R.id.et_username); et_password = (EditText) findViewById(R.id.et_password); } public void login(View view) throws Exception{ String username = et_username.getText().toString(); String password = et_password.getText().toString(); if (TextUtils.isEmpty(username)||TextUtils.isEmpty(password)) { Toast.makeText(this, "用户名和密码不能为空", Toast.LENGTH_SHORT); }else{ String path = getApplicationContext().getResources().getString(R.string.requesturl); StringBuilder sb = new StringBuilder(); try { sb.append(path).append("?").append("username=").append(URLEncoder.encode(username, "utf-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); throw new RuntimeException("请输入正确的编码集"); } sb.append("&").append("password=").append(password); String reqpath = sb.toString(); URL url = new URL(reqpath); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); if (conn.getResponseCode() == 200 ) { Toast.makeText(getApplicationContext(), "登录成功", Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(getApplicationContext(), "登录失败", Toast.LENGTH_SHORT).show(); } } } }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="用户名" /> <EditText android:id="@+id/et_username" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入用户名" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="密 码" /> <EditText android:id="@+id/et_password" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="textPassword" android:hint="请输入密码" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="login" android:text="登录" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="requesturl">http://192.168.1.101:80/LoginForWeb/LoginServlet</string> </resources>
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.login" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
效果图:
2、post请求:
android系统引入了一个第三方的框架 HttpClient,他就是对http协议的一个封装
文件上传:我们使用三方开源框架upload
在android端我们也使用HttpClient来实现文件的上传:HttpClient的版本必须在3.0之上。
练习(1、普通的post请求 2、利用HttpClient实现get、post请求 3、文件上传):
package com.shellway.login.activity; import com.shellway.login.activity.R; import com.shellway.login.service.LoginService; import android.support.v7.app.ActionBarActivity; import android.text.TextUtils; import android.annotation.SuppressLint; import android.os.Bundle; import android.os.StrictMode; import android.view.View; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends ActionBarActivity { LoginService service ; private EditText et_username; private EditText et_password; private EditText et_filename; @SuppressLint("NewApi") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); service = new LoginService(); et_username = (EditText) findViewById(R.id.et_username); et_password = (EditText) findViewById(R.id.et_password); et_filename = (EditText) findViewById(R.id.et_file); StrictMode.ThreadPolicy policy=new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); } public void login(View view){ String username = et_username.getText().toString(); String password = et_password.getText().toString(); String filename = et_filename.getText().toString(); if (TextUtils.isEmpty(username)||TextUtils.isEmpty(password)) { Toast.makeText(this, "用户名和密码不能为空", Toast.LENGTH_SHORT).show(); }else{ String path = this.getResources().getString(R.string.requesturl); try { // boolean result = service.loginByGet(path, username, password); // boolean result = service.loginByPost(path, username, password); // boolean result = service.loginHttpClientByGet(path, username, password); // boolean result = service.loginHttpClientByPost(path, username, password); boolean result = service.fileUpload(path, username, password, filename); if (result) { Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show(); } } } }
package com.shellway.login.service; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.multipart.FilePart; import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; import org.apache.commons.httpclient.methods.multipart.Part; import org.apache.commons.httpclient.methods.multipart.StringPart; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; public class LoginService { /** * 普通的以GET方式与服务器进行交互 * @param path 服务器连接路径 * @param username 用户名 * @param password 用户密码 * @return * @throws Exception * @throws IOException */ public boolean loginByGet(String path,String username,String password) { StringBuilder sb = new StringBuilder(path); try { sb.append("?").append("username=").append(URLEncoder.encode(username, "utf-8")); sb.append("&").append("password=").append(password); } catch (UnsupportedEncodingException e) { e.printStackTrace(); throw new RuntimeException("请输入正确的编码集"); } String reqpath = sb.toString(); System.out.println(reqpath); URL url; HttpURLConnection conn; try { url = new URL(reqpath); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); if (conn.getResponseCode() == 200 ) { return true; } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("连接网络失败"); } return false; } /** * 普通的以POST方式与服务器进行交互 * @param path 服务器连接路径 * @param username 用户名 * @param password 用户密码 * @return * @throws Exception * @throws IOException */ public boolean loginByPost(String path,String username,String password) throws Exception { StringBuilder sb = new StringBuilder(); sb.append("username=").append(URLEncoder.encode(username,"utf-8")).append("&"); sb.append("password=").append(password); byte[] entity = sb.toString().getBytes(); URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setConnectTimeout(5000); //设置实体参数 conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("Content-Length", entity.length+""); conn.setDoOutput(true); OutputStream os = conn.getOutputStream(); os.write(entity); if (conn.getResponseCode() == 200 ) { return true; } return false; } /** * 通过第三方HttpClient来实现以GET方式与服务器进行连接 * @param path 服务器连接路径 * @param username 用户名 * @param password 用户密码 * @return * @throws Exception * @throws IOException */ public boolean loginHttpClientByGet(String path,String username, String password) throws Exception, IOException{ //拼请求路径 StringBuilder sb = new StringBuilder(path); sb.append("?"); sb.append("username=").append(URLEncoder.encode(username,"utf-8")).append("&"); sb.append("password=").append(password); //1、得到浏览器 HttpClient httpClient = new DefaultHttpClient(); //2、指定请求方式 HttpGet httpGet = new HttpGet(sb.toString()); //3、执行请求 HttpResponse response = httpClient.execute(httpGet); //4、得到响应码 int code = response.getStatusLine().getStatusCode(); if (code==200) { return true; } return false; } /** * 通过第三方HttpClient来实现以POST方式与服务器进行连接 * @param path 服务器连接路径 * @param username 用户名 * @param password 用户密码 * @return * @throws Exception * @throws IOException */ public boolean loginHttpClientByPost(String path,String username, String password) throws Exception, IOException{ //1、得到浏览器 HttpClient httpClient = new DefaultHttpClient(); //2、指定请求方式 HttpPost httpPost = new HttpPost(path); //3、设置实体参数 List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(); nameValuePair.add(new BasicNameValuePair("username",username)); nameValuePair.add(new BasicNameValuePair("password",password)); //4、构建一个实体,并初始化参数 UrlEncodedFormEntity entity = new UrlEncodedFormEntity(nameValuePair); //5、把实体数据设置到请求对象 httpPost.setEntity(entity); //6、执行请求 HttpResponse response = httpClient.execute(httpPost); //7、得到状态码 int code = response.getStatusLine().getStatusCode(); if (code==200) { return true; } return false; } /** * 通过第三方HttpClient来实现以POST方式的文件上传 * @param path 服务器连接路径 * @param username 用户名 * @param password 用户密码 * @param filename 客户端的上传文件(包含路径) * @return * @throws Exception * @throws IOException */ public boolean fileUpload(String path,String username,String password,String filename) throws Exception, IOException{ //1、获得浏览器 org.apache.commons.httpclient.HttpClient httpClient = new org.apache.commons.httpclient.HttpClient(); //2、确定请求方式 PostMethod postMethod = new PostMethod(path); //3、确定请求的参数 Part[] parts = new Part[]{new StringPart("username", username), new StringPart("password", password), new FilePart("file", new File(filename))}; //4、构建实体 MultipartRequestEntity entity = new MultipartRequestEntity(parts, postMethod.getParams()); //5、设置请求实体 postMethod.setRequestEntity(entity); //6、执行请求 int responseCode = httpClient.executeMethod(postMethod); //7、得到响应码 if(responseCode == 200){ return true; } return false; } }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="用户名" /> <EditText android:id="@+id/et_username" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入用户名" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="密 码" /> <EditText android:id="@+id/et_password" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="textPassword" android:hint="请输入密码" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="上传文件" /> <EditText android:id="@+id/et_file" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入文件路径" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="login" android:text="登录" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.shellway.login.activity" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.shellway.login.activity.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
结果图:
3、电话号码归属地查询:
我们使用android server(webservice)
webservice就相当于网络上的api
手机号码归属地查询官网:http://www.webxml.com.cn/zh_cn/index.aspx
package com.shellway.addressqurey; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import com.shellway.service.QueryService; import android.support.v7.app.ActionBarActivity; import android.text.TextUtils; import android.annotation.SuppressLint; import android.os.Bundle; import android.os.StrictMode; import android.view.View; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends ActionBarActivity { private EditText et_number; private TextView tv_info; private QueryService service; @SuppressLint("NewApi") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); service = new QueryService(); et_number = (EditText) findViewById(R.id.et_number); tv_info = (TextView) findViewById(R.id.tv_info); StrictMode.ThreadPolicy policy=new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); } public void query(View view) { String number = et_number.getText().toString(); if (TextUtils.isEmpty(number)) { Toast.makeText(this, "电话号码不能为空", Toast.LENGTH_SHORT).show(); }else{ String path = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx"; try { String contentXML = service.reqXML(); String content = contentXML.replace("string", number); byte[] length = content.getBytes(); URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type","application/soap+xml; charset=utf-8"); conn.setRequestProperty("Content-Length", length.length +""); conn.getDoOutput(); OutputStream os = conn.getOutputStream(); os.write(length); if (conn.getResponseCode()==200) { InputStream is = conn.getInputStream(); String result = service.getNumber(is); if (result!=null) { tv_info.setText(result); } Toast.makeText(this, "查询成功", Toast.LENGTH_SHORT).show(); } }catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "查询失败", Toast.LENGTH_SHORT).show(); } } } }
package com.shellway.service; import java.io.ByteArrayOutputStream; import java.io.InputStream; import org.xmlpull.v1.XmlPullParser; import android.util.Xml; //手机号码归属地查询官网:http://www.webxml.com.cn/zh_cn/index.aspx public class QueryService { /**得到需要向服务器发送的信息 POST /WebServices/MobileCodeWS.asmx HTTP/1.1 Host: webservice.webxml.com.cn Content-Type: application/soap+xml; charset=utf-8 Content-Length: length <?xml version="1.0" encoding="utf-8"?> <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"> <soap12:Body> <getMobileCodeInfo xmlns="http://WebXml.com.cn/"> <mobileCode>string</mobileCode> <userID>string</userID> </getMobileCodeInfo> </soap12:Body> </soap12:Envelope> */ public String reqXML() throws Exception{ //加载需要发送的内容信息 InputStream is = this.getClass().getClassLoader().getResourceAsStream("request.xml"); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while((len = is.read(buffer)) != -1){ bos.write(buffer, 0, len); } bos.close(); is.close(); String reqContent = bos.toString(); return reqContent; } /**从服务器发回的输入流中解析出里面我们需要的内容信息 HTTP/1.1 200 OK Content-Type: application/soap+xml; charset=utf-8 Content-Length: length <?xml version="1.0" encoding="utf-8"?> <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"> <soap12:Body> <getMobileCodeInfoResponse xmlns="http://WebXml.com.cn/"> <getMobileCodeInfoResult>string</getMobileCodeInfoResult> </getMobileCodeInfoResponse> </soap12:Body> </soap12:Envelope> */ public String getNumber(InputStream is) throws Exception{ //得到解析器 XmlPullParser parser = Xml.newPullParser(); //设置解析器 parser.setInput(is, "utf-8"); //得到事件类型 int eventType = parser.getEventType(); //开始解析 while(eventType != XmlPullParser.END_DOCUMENT ){ switch (eventType) { case XmlPullParser.START_TAG: if ("getMobileCodeInfoResult".equals(parser.getName())){ return parser.nextText(); } break; default: break; } eventType = parser.next(); } return null; } }
<?xml version="1.0" encoding="utf-8"?> <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"> <soap12:Body> <getMobileCodeInfo xmlns="http://WebXml.com.cn/"> <mobileCode>string</mobileCode> <userID></userID> </getMobileCodeInfo> </soap12:Body> </soap12:Envelope>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="电话号码" /> <EditText android:id="@+id/et_number" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入要查询的电话号码" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="query" android:text="查询" /> <TextView android:id="@+id/tv_info" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="查询信息" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.shellway.addressqurey" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
结果截图:
总结:
Bitmap BitmapFactory
ScrollView
Http : URL HttpURLConnection conn 联网权限
xml
json
http get /post
HttpClient
文件上传
注意啦:本Android系列复习笔记后面会继续更新。。。。。。