Android完全支持JDK本身的TCP,UDP网络通信API,也可以使用ServerSocket,Socket来建立基于TCP/IP协议的网络通信,还可以使用DatagramSocket,Datagrampacket,MulticastSocket来建立 基于UDP的协议网络通信
同时支持JDK提供的URL,URLConnection等网络通信API.
Andoirdgip内置了Apache的HttpClient,这样可以非常方便的发送HTTP请求,并获取HTTP响应.
服务器
package com.itheima.server; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; /** * ServerSocket 服务端 * @Decription TODO * @author 刘楠 * * @time2016-2-22下午4:54:59 */ public class MyServer { public static ArrayList<Socket> socketList = new ArrayList<Socket>(); public static void main(String[] args) { try { //建立serversocket ServerSocket serverSocket = new ServerSocket(25000); //服务器一直在运行状态 while(true){ //开始监听 Socket socket = serverSocket.accept(); socketList.add(socket); //启动新的线程 new ServerThread(socket).start(); } } catch (IOException e) { e.printStackTrace(); } } } /* 线程类 */ package com.itheima.server; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; public class ServerThread extends Thread { private Socket socket; public ServerThread(Socket socket) throws IOException { //初始化 this.socket = socket; } @Override public void run() { String ip = socket.getInetAddress().getHostAddress(); System.out.println("ip:"+ip); BufferedReader br=null; OutputStream out = null; try { br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8")); out = socket.getOutputStream(); String content = null; while((content=br.readLine())!=null){ System.out.println("来自客户端:"+content); //手动加上换行 符,不然没客户端收不到 out.write((content+"\n").toUpperCase().getBytes("utf-8")); System.out.println("服务发出去了:"); } out.close(); br.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
布局文件
<?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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context="com.itheima.mutithreadclient.MainActivity"> <!--接收用户输入的内容--> <EditText android:id="@+id/input" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="请输入要发送的内容"/> <Button android:id="@+id/send" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="发送"/> <!--接收服务返回的内容--> <TextView android:id="@+id/show" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
子线程
/** * 线程类 * Created by 刘楠 on 2016-02-22 17:51. */ public class ClientThread implements Runnable{ private static final String TAG = "ClientThread"; private Socket s; // 定义向UI线程发送消息的Handler对象 private Handler handler; // 定义接收UI线程的消息的Handler对象 public Handler revHandler; // 该线程所处理的Socket所对应的输入流 BufferedReader br = null; OutputStream os = null; public ClientThread(Handler handler) { this.handler = handler; } public void run() { try { s = new Socket("192.168.1.103", 25000); br = new BufferedReader(new InputStreamReader( s.getInputStream())); os = s.getOutputStream(); // 启动一条子线程来读取服务器响应的数据 new Thread() { @Override public void run() { String content = null; // 不断读取Socket输入流中的内容 try { while ((content = br.readLine()) != null) { // 每当读到来自服务器的数据之后,发送消息通知程序 // 界面显示该数据 Message msg = new Message(); msg.what = 0x123; msg.obj = content; handler.sendMessage(msg); Log.i(TAG,"服务返回"+content); } } catch (IOException e) { e.printStackTrace(); } } }.start(); // 为当前线程初始化Looper Looper.prepare(); // 创建revHandler对象 revHandler = new Handler() { @Override public void handleMessage(Message msg) { // 接收到UI线程中用户输入的数据 if (msg.what == 0x345) { // 将用户在文本框内输入的内容写入网络 try { //手动加上换行符 os.write((msg.obj.toString() + "\r\n") .getBytes("utf-8")); Log.i(TAG, "输入的" + msg.obj.toString()); } catch (Exception e) { e.printStackTrace(); } } } }; // 启动Looper Looper.loop(); } catch (SocketTimeoutException e1) { System.out.println("网络连接超时!!"); } catch (Exception e) { e.printStackTrace(); } } }
Activity
/** * * 使用ServketSocket做服务通信 * * * @author 刘楠 */ public class MainActivity extends AppCompatActivity { private EditText input; private TextView show; private ClientThread clientThread; private Button send; private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); input = (EditText) findViewById(R.id.input); show = (TextView) findViewById(R.id.show); send = (Button) findViewById(R.id.send); /** * 接收到消息要就显示 */ handler = new Handler(){ @Override public void handleMessage(Message msg) { if(msg.what==0x123){ show.append("\n"+msg.obj.toString()); } } }; //初始化子线程 clientThread = new ClientThread(handler); //启动子线程 new Thread(clientThread).start(); send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String str = input.getText().toString().trim(); Message msg=new Message(); msg.what=0x345; msg.obj=str; //把内容发给子线程 clientThread.revHandler.sendMessage(msg); //清空文本框 input.setText(""); } }); } }
<!--添加网络权限--> <uses-permission android:name="android.permission.INTERNET"/>
布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <EditText android:id="@+id/et_url" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="请输入URL图片地址"/> <Button android:onClick="display" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="显示图片地址"/> <ImageView android:id="@+id/show" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
Activity
/** * URL连接网络 * 获取URL地址 * 打开流,获取流的内容 * */ public class MainActivity extends AppCompatActivity { /* 标识表示成功 */ private static final int SUCCESS = 1; //路径写死了 也可以获取的方式 private String path ="http://img2.imgtn.bdimg.com/it/u=4114593003,3380074209&fm=21&gp=0.jpg"; /* 图片 */ Bitmap bitmap; /* 显示图片 */ ImageView show; /* 输入的URL */ private EditText et_url; private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_url = (EditText) findViewById(R.id.et_url); show = (ImageView) findViewById(R.id.show); handler = new Handler(){ @Override public void handleMessage(Message msg) { switch(msg.what){ case SUCCESS: show.setImageBitmap(bitmap); break; } } }; } /** * 获取输入的地址并显示图片 * @param v 当前对象 */ public void display(View v){ String strPath = et_url.getText().toString().trim(); if(TextUtils.isEmpty(strPath)){ Toast.makeText(this,"输入的路径不能为空",Toast.LENGTH_SHORT).show(); return ; } new Thread(new Runnable() { @Override public void run() { try { //获取URL URL url = new URL(path); //打开流获取资源 InputStream in = url.openStream(); //使用BitmapFactory转换为Bitmap bitmap = BitmapFactory.decodeStream(in); //获取消息 Message msg = Message.obtain(); msg.what=SUCCESS; msg.obj=bitmap; handler.sendMessage(msg); //关闭 // in.close(); //把文件保存到本地 in =url.openStream(); OutputStream out = openFileOutput("test.png",MODE_PRIVATE); byte [] buf = new byte [1024]; int len=0; while((len=in.read(buf))!=-1){ out.write(buf,0,len); } out.close(); in.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }).start(); } }
添加网络权限
<!--添加网络权限--> <uses-permission android:name="android.permission.INTERNET"/>
使用URLConnection连接网络
*Get方式只要 获取请求地址把请求参数拼接在URL地址后面"?username="+user+"&password="+password
* openConnection
* 设置请求头信息
* connect()建立实际连接
* 获取输入流conn.getInputStream
* 读取输入流中的内容
*
* Post方式,
* 请求地址
* ,将参数单独拼接为一个字符串params="username="+user+"&password="+password
* openConnection
* 设置请求头信息
* connect()建立实际连接
* setDoOuput(true)
* setDoInput(true)
* 写出参数conn.getOutPutStream().write(params.getBytes());
* 获取输入流conn.getInputStream
* 读取输入流中的内容
服务器Servlet
/** * LoginServlet * @Decription 处理登录请求的Servlet * @author 刘楠 * * @time2016-2-22下午9:40:48 */ @WebServlet(urlPatterns={"/login"}) public class LoginServlet extends HttpServlet { @SuppressWarnings("deprecation") public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 获取用户名与密码并转换为UTF-8 */ String user = request.getParameter("username"); /*String encode = URLEncoder.encode(user,"iso8859-1"); String decode = URLDecoder.decode(encode, "UTF-8");*/ String username =new String(user.getBytes("iso8859-1"),"utf-8"); System.out.println("用户名:"+username); String pwd=request.getParameter("password"); String password = new String(pwd.getBytes("iso8859-1"), "UTF-8"); System.out.println("密码:"+password); /* * 这里写死用户名与密码, * 正常是去数据库查询 */ PrintWriter writer = response.getWriter(); if("admin".equals(username)&& "admin".equals(password)){ writer.write("SUCCESS"); }else{ writer.write("FAILURE"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("================post==============="); request.setCharacterEncoding("UTF-8"); String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("username:"+username+",password: "+password); if("admin".equals(username) && "admin".equals(password)){ response.getWriter().print("SUCCESS"); }else{ response.getWriter().print("failure"); } } }
布局
<?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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context="com.itheima.urlconnection.MainActivity"> <EditText android:id="@+id/et_user" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入用户名"/> <EditText android:id="@+id/et_pwd" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPassword" android:hint="请输入密码"/> <Button android:onClick="get" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="GET请求"/> <Button android:onClick="post" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="POST 请求"/> <TextView android:id="@+id/show" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
Activity
/** * 使用URLConnection连接网络 *Get方式只要 获取请求地址把请求参数拼接在URL地址后面"?username="+user+"&password="+password * openConnection * 设置请求头信息 * connect()建立实际连接 * 获取输入流conn.getInputStream * 读取输入流中的内容 * * Post方式, * 请求地址 * ,将参数单独拼接为一个字符串params="username="+user+"&password="+password * openConnection * 设置请求头信息 * connect()建立实际连接 * setDoOuput(true) * setDoInput(true) * 写出参数conn.getOutPutStream().write(params.getBytes()); * 获取输入流conn.getInputStream * 读取输入流中的内容 * * */ public class MainActivity extends AppCompatActivity { private static final int SUCCESS = 1; private static final int ERROR =2 ; private static final String TAG ="MainActivity" ; /* 请求的路径 */ private String path="http://192.168.1.103:8080/Login/login"; private TextView show; private EditText et_user; private EditText et_pwd; /* Handler 消息处理 */ private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* 初始化 */ et_user = (EditText) findViewById(R.id.et_user); et_pwd = (EditText) findViewById(R.id.et_pwd); show = (TextView) findViewById(R.id.show); handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ case SUCCESS: show.setText(msg.obj.toString()); break; case ERROR: Toast.makeText(MainActivity.this,"网络异常",Toast.LENGTH_SHORT).show(); break; } } }; } /** * get 方式请求 * @param v 当前组件 */ public void get(View v){ String username = et_user.getText().toString().trim(); String password = et_pwd.getText().toString().trim(); if(TextUtils.isEmpty(username) || TextUtils.isEmpty(password)){ Toast.makeText(this,"用户名或者密码不能为空",Toast.LENGTH_SHORT).show(); return ; } final String urlName =path+"?username="+username+"&password="+password; /* get请求 */ new Thread(){ @Override public void run() { try { //获取请求URL地址 URL url=new URL(urlName); //打开连接 URLConnection conn = url.openConnection(); //设置超时时间 conn.setConnectTimeout(5000); // 设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"); //建立实际连接 conn.connect(); //获取所有的行响应 头字段 Map<String,List<String>> map = conn.getHeaderFields(); Set<String> keySet = map.keySet(); for (String key:keySet ) { Log.i(TAG,"key"+key+"------------>"+map.get(key)); } //定义输入流来获取URL的响应 InputStream in = conn.getInputStream(); ByteArrayOutputStream bas= new ByteArrayOutputStream(); int len=0; byte [] buf = new byte[1024]; while((len=in.read(buf))!=-1){ bas.write(buf,0,len); } //转换为字符串 String result=bas.toString(); //设置消息对象 Message msg = Message.obtain(); //成功就发送SUCCESS msg.what=SUCCESS; msg.obj=result; //发送 handler.sendMessage(msg); } catch (Exception e) { e.printStackTrace(); //出异常就发送ERROR Message msg = Message.obtain(); msg.what=ERROR; handler.sendMessage(msg); } } }.start(); } /** * post 方式请求 * @param v 当前组件 */ public void post(View v){ String username = et_user.getText().toString().trim(); String password = et_pwd.getText().toString().trim(); if(TextUtils.isEmpty(username) || TextUtils.isEmpty(password)){ Toast.makeText(this,"用户名或者密码不能为空",Toast.LENGTH_SHORT).show(); return ; } final String params="username="+username+"&password="+password; /* post请求 */ new Thread(){ @Override public void run() { try { //获取请求URL地址 URL url=new URL(path); //打开连接 URLConnection conn = url.openConnection(); //设置超时时间 conn.setConnectTimeout(5000); // 设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"); /* post请求必须有以下2行 */ conn.setDoOutput(true); conn.setDoInput(true); OutputStream out = conn.getOutputStream(); out.write(params.getBytes()); //建立实际连接 //获取所有的行响应 头字段 Map<String,List<String>> map = conn.getHeaderFields(); Set<String> keySet = map.keySet(); for (String key:keySet ) { Log.i(TAG,"key"+key+"------------>"+map.get(key)); } //定义输入流来获取URL的响应 InputStream in = conn.getInputStream(); ByteArrayOutputStream bas= new ByteArrayOutputStream(); int len=0; byte [] buf = new byte[1024]; while((len=in.read(buf))!=-1){ bas.write(buf,0,len); } //转换为字符串 String result=bas.toString(); //设置消息对象 Message msg = Message.obtain(); //成功就发送SUCCESS msg.what=SUCCESS; msg.obj=result; //发送 handler.sendMessage(msg); } catch (Exception e) { e.printStackTrace(); //出异常就发送ERROR Message msg = Message.obtain(); msg.what=ERROR; handler.sendMessage(msg); } } }.start(); } }
添加网络权限
<!--添加网络权限--> <uses-permission android:name="android.permission.INTERNET"/>
和URLConnection非常类似只获取连接为HttpURULConnection
/**
* 使用HttpURLConnection连接网络
*Get方式只要 获取请求地址把请求参数拼接在URL地址后面"?username="+user+"&password="+password
* openConnection
* 设置请求方法setRequestMethod("GET")必须大写
*
* 获取输入流conn.getInputStream
* 读取输入流中的内容
*
* Post方式,
* 请求地址
* ,将参数单独拼接为一个字符串params="username="+user+"&password="+password
* openConnection
* 设置请求方法setRequestMethod("POST")必须大写
* setDoOuput(true)
* setDoInput(true)
* 写出参数conn.getOutPutStream().write(params.getBytes());
* 获取输入流conn.getInputStream
* 读取输入流中的内容
*
*
*/
/** * 使用HttpURLConnection连接网络 *Get方式只要 获取请求地址把请求参数拼接在URL地址后面"?username="+user+"&password="+password * openConnection * 设置请求方法setRequestMethod("GET")必须大写 * * 获取输入流conn.getInputStream * 读取输入流中的内容 * * Post方式, * 请求地址 * ,将参数单独拼接为一个字符串params="username="+user+"&password="+password * openConnection * 设置请求方法setRequestMethod("POST")必须大写 * setDoOuput(true) * setDoInput(true) * 写出参数conn.getOutPutStream().write(params.getBytes()); * 获取输入流conn.getInputStream * 读取输入流中的内容 * * */ public class MainActivity extends AppCompatActivity{ private static final int SUCCESS = 1; private static final int ERROR =2 ; private static final String TAG ="MainActivity" ; /* 请求的路径 */ private String path="http://192.168.1.100:8080/Login/login"; private TextView show; private EditText et_user; private EditText et_pwd; /* Handler 消息处理 */ private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* 初始化 */ et_user = (EditText) findViewById(R.id.et_user); et_pwd = (EditText) findViewById(R.id.et_pwd); show = (TextView) findViewById(R.id.show); handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ case SUCCESS: show.setText(msg.obj.toString()); break; case ERROR: Toast.makeText(MainActivity.this, "网络异常", Toast.LENGTH_SHORT).show(); break; } } }; } /** * get 方式请求 * @param v 当前组件 */ public void get(View v){ String username = et_user.getText().toString().trim(); String password = et_pwd.getText().toString().trim(); if(TextUtils.isEmpty(username) || TextUtils.isEmpty(password)){ Toast.makeText(this,"用户名或者密码不能为空",Toast.LENGTH_SHORT).show(); return ; } final String urlName =path+"?username="+username+"&password="+password; /* get请求 */ new Thread(){ @Override public void run() { try { //获取请求URL地址 URL url=new URL(urlName); //打开连接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //设置超时时间 conn.setConnectTimeout(5000); //设置请求方式 conn.setRequestMethod("GET"); //获取响应码 int code = conn.getResponseCode(); if(code==200) { //获取所有的行响应 头字段 Map<String, List<String>> map = conn.getHeaderFields(); Set<String> keySet = map.keySet(); for (String key : keySet) { Log.i(TAG, "key" + key + "------------>" + map.get(key)); } //定义输入流来获取URL的响应 InputStream in = conn.getInputStream(); ByteArrayOutputStream bas = new ByteArrayOutputStream(); int len = 0; byte[] buf = new byte[1024]; while ((len = in.read(buf)) != -1) { bas.write(buf, 0, len); } //转换为字符串 String result = bas.toString(); //设置消息对象 Message msg = Message.obtain(); //成功就发送SUCCESS msg.what = SUCCESS; msg.obj = result; //发送 handler.sendMessage(msg); }else{ //出异常就发送ERROR Message msg = Message.obtain(); msg.what=ERROR; handler.sendMessage(msg); } } catch (Exception e) { e.printStackTrace(); //出异常就发送ERROR Message msg = Message.obtain(); msg.what=ERROR; handler.sendMessage(msg); } } }.start(); } /** * post 方式请求 * @param v 当前组件 */ public void post(View v){ String username = et_user.getText().toString().trim(); String password = et_pwd.getText().toString().trim(); if(TextUtils.isEmpty(username) || TextUtils.isEmpty(password)){ Toast.makeText(this,"用户名或者密码不能为空",Toast.LENGTH_SHORT).show(); return ; } final String params="username="+username+"&password="+password; /* post请求 */ new Thread(){ @Override public void run() { try { //获取请求URL地址 URL url=new URL(path); //打开连接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //设置超时时间 conn.setConnectTimeout(5000); //设置请求方式 conn.setRequestMethod("POST"); /* post请求必须有以下2行 */ conn.setDoOutput(true); OutputStream out = conn.getOutputStream(); out.write(params.getBytes()); //建立实际连接 //获取所有的行响应 头字段 Map<String,List<String>> map = conn.getHeaderFields(); Set<String> keySet = map.keySet(); for (String key:keySet ) { Log.i(TAG,"key"+key+"------------>"+map.get(key)); } //定义输入流来获取URL的响应 InputStream in = conn.getInputStream(); ByteArrayOutputStream bas= new ByteArrayOutputStream(); int len=0; byte [] buf = new byte[1024]; while((len=in.read(buf))!=-1){ bas.write(buf,0,len); } //转换为字符串 String result=bas.toString(); //设置消息对象 Message msg = Message.obtain(); //成功就发送SUCCESS msg.what=SUCCESS; msg.obj=result; //发送 handler.sendMessage(msg); } catch (Exception e) { e.printStackTrace(); //出异常就发送ERROR Message msg = Message.obtain(); msg.what=ERROR; handler.sendMessage(msg); } } }.start(); } }
/** * 使用HttpClient做网络请求 5.0过期,6.0不可用 * * 建立HttpClient对象 get请求 建立httpGet对象 * setParams来设置参数 * 也可以将参数拼接在URL地址后面 * * post请求 建立HttpPost对象 * 设置请求体 * setEntity * new UrlEncodedFormEntity(List<? extends NameValuePair>) * 设置参数 * * 获取行响应码,判断, * 获取行响应体 * * * * @author 刘楠 * * 2016-2-23上午12:04:06 */ public class MainActivity extends Activity { private static final int SUCCESS = 1; private static final int ERROR = 2; private static final String TAG = "MainActivity"; /* * 请求的路径 */ private String path = "http://192.168.1.100:8080/Login/login"; private TextView show; private EditText et_user; private EditText et_pwd; private HttpClient client; /* * Handler 消息处理 */ private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* * 初始化 */ client = new DefaultHttpClient(); et_user = (EditText) findViewById(R.id.et_user); et_pwd = (EditText) findViewById(R.id.et_pwd); show = (TextView) findViewById(R.id.show); handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case SUCCESS: show.setText(msg.obj.toString()); break; case ERROR: Toast.makeText(MainActivity.this, "网络异常", Toast.LENGTH_SHORT).show(); break; } } }; } /** * get 方式请求 * * @param v * 当前组件 */ private String urlName ; public void get(View v) { String username = et_user.getText().toString().trim(); String password = et_pwd.getText().toString().trim(); if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) { Toast.makeText(this, "用户名或者密码不能为空", Toast.LENGTH_SHORT).show(); return; } try { urlName = path + "?username=" + URLEncoder.encode(username, "UTF-8") + "&password=" + URLEncoder.encode(password, "UTF-8"); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } /* * get请求 */ new Thread() { @Override public void run() { try { HttpGet get = new HttpGet(urlName); /** * 可以使用HttpParams设置参数 HttpParams params = new * BasicHttpParams(); */ // 开始执行 HttpResponse response = client.execute(get); // 获取响应码 int code = response.getStatusLine().getStatusCode(); if (code == 200) { // 获取内容响应体中的内容 InputStream in = response.getEntity().getContent(); ByteArrayOutputStream bas = new ByteArrayOutputStream(); int len = 0; byte[] buf = new byte[1024]; while ((len = in.read(buf)) != -1) { bas.write(buf, 0, len); } String result = bas.toString(); in.close(); //设置消息 Message msg = Message.obtain(); msg.what = SUCCESS; msg.obj = result; handler.sendMessage(msg); } else { Message msg = Message.obtain(); msg.what = SUCCESS; handler.sendMessage(msg); } } catch (Exception e) { e.printStackTrace(); } } }.start(); } /** * post 方式请求 * * @param v * 当前组件 * @throws UnsupportedEncodingException */ public void post(View v) { final String username = et_user.getText().toString().trim(); final String password = et_pwd.getText().toString().trim(); if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) { Toast.makeText(this, "用户名或者密码不能为空", Toast.LENGTH_SHORT).show(); return; } /* * post请求 */ new Thread() { @Override public void run() { try { //建立Post请求 HttpPost post = new HttpPost(path); List<NameValuePair> parameters = new ArrayList<NameValuePair>(); parameters.add(new BasicNameValuePair("username", username)); parameters.add(new BasicNameValuePair("password", password)); //设置请求体与字符编码 post.setEntity(new UrlEncodedFormEntity(parameters,"UTF-8") ); //执行 HttpResponse response = client.execute(post); //获取响应码 int code = response.getStatusLine().getStatusCode(); if (code == 200) { // 获取内容响应体中的内容 InputStream in = response.getEntity().getContent(); ByteArrayOutputStream bas = new ByteArrayOutputStream(); int len = 0; byte[] buf = new byte[1024]; while ((len = in.read(buf)) != -1) { bas.write(buf, 0, len); } String result = bas.toString(); in.close(); //设置消息 Message msg = Message.obtain(); msg.what = SUCCESS; msg.obj = result; handler.sendMessage(msg); } else { Message msg = Message.obtain(); msg.what = SUCCESS; handler.sendMessage(msg); } } catch (Exception e) { e.printStackTrace(); } } }.start(); } }
goBack():后退
goForward():前进
loadUrl(String url):加载指定URL的网页
boolean zoomln():放大网页
zoomOut():缩小网页
布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <EditText android:id="@+id/et_url" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入url网址"/> <WebView android:id="@+id/wv_show" android:layout_width="match_parent" android:layout_height="match_parent"> </WebView> </LinearLayout>
Activity
/** * WebView小型浏览器 * */ public class MainActivity extends AppCompatActivity { /* 接收输入的URL */ private EditText et_url; /* 显示网页内容 */ private WebView wv_show; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_url = (EditText) findViewById(R.id.et_url); wv_show = (WebView) findViewById(R.id.wv_show); } @Override public boolean onKeyDown(int keyCode,KeyEvent event) { if(keyCode==KeyEvent.KEYCODE_MENU){ String urlStr = et_url.getText().toString().trim(); //加载 wv_show.loadUrl(urlStr); return true; } return false; } }
添加权限
<uses-permission android:name="android.permission.INTERNET"/>
WebView提供了一具
loadData(String data,String mimeType ,String encoding)方法用于加载HTML,这个方法加载中文时会有乱码
还有一个
loadDataWithURL(String data,String mimeType ,String encoding,String historyUrl)方法是第一个方法的加强,
data:指定的HTML代码
mimeType:指定HTML代码的MIME类型,对象HTML代码可指定为text/html
encoding:指定HTML代码编码所有的字符集:UTF-8
布局中只有一个WebView
/** * WebView显示HTML */ public class MainActivity extends AppCompatActivity { private WebView webView_show; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //获取webView组件 webView_show = (WebView) findViewById(R.id.webView_show); StringBuilder sb = new StringBuilder(); sb.append("<html>"); sb.append("<head>"); sb.append("<title> 欢迎WebView显示HTML</title>"); sb.append("</head>"); sb.append("<body>"); sb.append("<h1 align='center' style='color:red'>显示中文标题</h1>"); sb.append("</body>"); sb.append("</html>"); //加载并显示HTML这个中文会显示乱码 //webView_show.loadData(sb.toString(),"text/html","utf-8"); webView_show.loadDataWithBaseURL(null,sb.toString(),"text/html","utf-8",null); } }
Html在assets目录下
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>JS 调用</title> </head> <body> <!-- 注意此处的myObj是Android暴露出来的对象 --> <input type="button" value="弹Toast" onclick="person.show();"/> <input type="button" value="图书列表" onclick="person.showList();"/> </body> </html>
布局
<?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"> <WebView android:id="@+id/webView" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>
JAVABean:
/** * Created by 刘楠 on 2016-02-23 09:00. */ public class Person { private String name; private int age; private Context mContext; public Person(Context context){ this.mContext = context; } public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @JavascriptInterface public void show(){ Toast.makeText(mContext,"姓名"+this.name+",年龄:"+age,Toast.LENGTH_SHORT).show(); } /** * 这具注解只能用在方法 */ @JavascriptInterface public void showList(){ new AlertDialog.Builder(mContext) //设置标题 .setTitle("人员列表") .setIcon(R.mipmap.ic_launcher) .setItems(new String [] {"JAVA","Android","C++","C","PYTHON"},null) .setPositiveButton("确定",null) .setNegativeButton("取消",null) .create().show(); } }
Activity
/** * WebView使用JavaScript * */ public class MainActivity extends AppCompatActivity { private WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = (WebView) findViewById(R.id.webView); webView.loadUrl("file:///android_asset/test.html"); //获取WebView设置对象 WebSettings webSettings = webView.getSettings(); //启用javaScript webSettings.setJavaScriptEnabled(true); Person person = new Person(this); person.setName("张三"); person.setAge(18); //传递对象 webView.addJavascriptInterface(person, "person"); } }