一、所谓的网络编程就是在手机端使用TTP协议和服务器进行网络交互,并对服务器返回的数据进行解析。
二、调用百度网址
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
前端的代码很简单:就是放置了一个WebView的控件,这个控件的作用就是用来显示浏览器的。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webView=(WebView)findViewById(R.id.web_view);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("http://www.baidu.com");
}
(1)getSettings()中用来设置一些浏览器的属性,这里只是让WebView来支持javaScript脚本
(2)setWebViewClient()传入一个webViewClient实例,意思是当需要打开一个网页转到另一个网页的时候,我们希望目标网页仍在当前的WenView中显示,而不是打系统浏览器
(3)
android:usesCleartextTraffic=“true”
需要加权限
(4)WebView将回调进行分类集合就会出现两个类:WebViewClient和WebChromeClient
WebViewClient:在影响【View】的事件到来时,会通过WebViewClient中的方法回调通知用户(帮WebView处理各种通知,请求事件的)
WebChromeClient:当影响【浏览器】的事件到来时,就会通过WebChromeClient中的方法回调通知用法。
三、HTTP协议的解释
(1)就是客户端像服务器端发出一条HTTP请求,然后服务器端收到请求后会返回一些数据给客户端,然后客户端在对这些数据进行解析和处理
(2)刚才的WebView(客户端)就是像百度浏览器(服务器)发起了一个HTTP请求,然后服务器分析出我们想访问的是百度浏览器,于是把该网页的HTML代码进行返回,然后WebView再调用手机的浏览器内核对返回的HTML代码进行解析,最终将页面展示出来。
(所以WebView相当是封装好了发送HTTP请求,接受服务响应,解析返回的数据,以及最终的展示)
四、一个浏览器的工作原理
(1)客户端发送HTTP请求
(2)服务器接收请求并分析
(3)服务器返回数据
(4)客户端对接受返回的数据
(5)客户端对返回的数据进行分析和解析
(6)展示
其中(1)(4)(5)(6)是我们做的,(2)(3)是服务器端做的
下面我们就来自己介绍怎么发送HTTP请求和解析数据
五、发送HTTP请求并接受返回的数据
第一种方法HttpURLConnection
思路:
(1)首先获取HttpURLConnection实例,先通过new出一个URL对象(这里包括要访问的网址),再利用这个URL对象调用openConnection()方法就可以得到HttpURLConnection对象。
(2)设置一下HTTP请求所用的方法,分为两种
GET:表示希望从服务器那里获取数据,POST:表示希望提交数据给服务器
connection.setRequestMethod(“GET”);
connection.setRequestMethod(“POST”);
(3)进行自由的定制
(4)用getInputStream()得到服务器返回的数据
(5)对获取到的输入流进行读取(这个输入流是针对客户端来说的。从服务器端输入到客户端)
(6)展示获取的数据
前端代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/send_request"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Send Request"
/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/response_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</ScrollView>
</LinearLayout>
ScrollView:通过这个控件可以通过滚动的方式查看屏幕以外的内容
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
TextView responseText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button sendRequest=(Button)findViewById(R.id.send_request);
responseText=(TextView)findViewById(R.id.response_text);
sendRequest.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v.getId()==R.id.send_request)
{
sendRequestWithHttpURLConnection();
}
}
public void sendRequestWithHttpURLConnection(){
new Thread(new Runnable(){
@Override
public void run() {
HttpURLConnection connection=null;
BufferedReader reader=null;
try{
//获取HttpURLConnection实例,先通过new出一个URL对象,再利用这个URL对象调用openConnection()方法就可以得到HttpURLConnection对象
URL url=new URL("https://www.baidu.com");
connection=(HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
//利用getInputStream()得到服务器返回的数据
InputStream in =connection.getInputStream();
//下面对获取到的输入流及逆行读取(这个输入流是针对客户端来说的。从服务器端输入到客户端)
reader=new BufferedReader(new InputStreamReader(in));
StringBuilder response=new StringBuilder();
String line;
while((line=reader.readLine())!=null)
{
response.append(line);
showResponse(response.toString());
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(reader!=null)
{
try{
reader.close();
}catch(IOException e){
e.printStackTrace();
}
}
if(connection!=null)
{
connection.disconnect();
}
}
}
}).start();
}
private void showResponse(final String response){
runOnUiThread(new Runnable() {
@Override
public void run() {
//在这里进行UI操作,将结果显示在页面上
responseText.setText(response);
}
});
}
以上代码涵盖了思路六步
注意:(1)
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
这两行代码就是自由定制(连接超时和读取超时的毫秒数)
(2)最后调用connection.disconnection()关闭掉HTTP链接
(3)在showResponse中用到 runOnUiThread()是因为不允许在子线程中进行UI操作,所以必须切换到主线程
(4)如果是想要提交数据给服务器,只需将HTTP请求改成POST,并在获取输入流之前把要提交的数据写出即可。每条数据都应该是以键值对的形式存在,数据与数据之间用&符号隔开,比如要提交用户名和密码,代码如下
connection.setRequestMethod("POST");
DataOutputStream out=new DataOutputStream(connection.getOutputStream());
out.writeBytes("username=admin&password=123456");
(5)InputStream类:字符缓冲输入流:把字符流存入到缓存,在到内存,提高读的效率
(6)结果是一堆乱码。这是因为百度浏览器给我们就是Html代码。需要我们自己解析,这个下一个博客会讲
第二种方法:使用OkHttp
需要添加依赖
步骤:(1)需要创建OkHttpClient对象(直接创建)
(2)因为要发送一条HTTP请求,所以要创建Request对象。在这里可以设置目标网络的地址,如果是POST,还需要在这里调用post()方法。
(3)调用newCall()方法来创建一个Call对象,并调用它的execute()方法来发送请求并且获取服务器返回的数据
(4)获取返回数据的具体内容
public void sendRequestWithOkHttp(){
new Thread(new Runnable(){
@Override
public void run() {
try {
//(1)创建OkHttpClient对象
OkHttpClient client = new OkHttpClient();
//(2)创建Request对象用于HTTP请求
Request request = new Request.Builder()
.url("http://www.baidu.com")//网址地址
.build();
//调用newCall()方法来创建一个Call对象,并调用它的execute()方法来发送请求并且获取服务器返回的数据 response就是回收到的数据
Response response = client.newCall(request).execute();
//获得具体内容(responseData 就是具体内容)
String responseData = response.body().string();
showResponse(responseData);
}catch(Exception e){
e.printStackTrace();
}
}
}).start();
}