安卓第七天笔记--网络编程一

时间:2021-02-05 19:24:03

安卓第七天笔记--网络编程一

安卓第七天笔记--网络编程一

 

Android对网络的支持

 

Android完全支持JDK本身的TCP,UDP网络通信API,也可以使用ServerSocket,Socket来建立基于TCP/IP协议的网络通信,还可以使用DatagramSocket,Datagrampacket,MulticastSocket来建立 基于UDP的协议网络通信

 

同时支持JDK提供的URL,URLConnection等网络通信API.

 

Andoirdgip内置了Apache的HttpClient,这样可以非常方便的发送HTTP请求,并获取HTTP响应.

 

1.Socket实现

服务器

 

安卓第七天笔记--网络编程一
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"/>

 

2.URL连接网络

安卓第七天笔记--网络编程一

 

布局

安卓第七天笔记--网络编程一
<?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"/>

 

3.URLConnection连接网络

 

使用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

 

安卓第七天笔记--网络编程一 View Code

 

3.1get请求与Post请求

 布局

安卓第七天笔记--网络编程一
<?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

安卓第七天笔记--网络编程一 View Code

 

添加网络权限

    <!--添加网络权限-->
<uses-permission android:name="android.permission.INTERNET"/>

4.Http网络连接

 

和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
* 读取输入流中的内容
*
*
*/

 

安卓第七天笔记--网络编程一 View Code

 

5.使用ApacheHttpClient

安卓第七天笔记--网络编程一 View Code

 

6.WebView

 

goBack():后退

goForward():前进

loadUrl(String url):加载指定URL的网页

boolean zoomln():放大网页

zoomOut():缩小网页

 

 安卓第七天笔记--网络编程一

布局

安卓第七天笔记--网络编程一 布局

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"/>

 

7.使用WebHTML加载HTML代码

安卓第七天笔记--网络编程一

 

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);



}

}
安卓第七天笔记--网络编程一

 

 

 

 

9.WebView使用JavaScript调用Android

安卓第七天笔记--网络编程一安卓第七天笔记--网络编程一

 

  • 步骤:
  •  

  • 1.调用WebView的get getSettings方法获取WebSettings
  • 2.启用JAVAScript调用功能
  • webSettings.setJavaScriptEnable(true)
  • 3.调用webView的addJavaScript(Object obj,String name)方法
  • 4.在javaScript脚本中通过刚才暴露的name对象调用Android
  • 5.对象的方法上必须加上注解
  • /**
    •  * 这具注解只能用在方法
      •  */
        • @JavascriptInterface
 

 

 

 

 

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");

}

}

安卓第七天笔记--网络编程一