一、WebView的用法 当我们需要在应用中浏览网页,但又不能打开系统浏览器的时候,我们可以利用Android自带的WebView控件来实现这一要求。 新建一个WebViewTest项目,修改activity_main.xml代码。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" 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" tools:context="com.studio.webviewtest.MainActivity"> <WebView android:id="@+id/web_view" android:layout_width="match_parent" android:layout_height="match_parent"> </WebView> </RelativeLayout>这里我们在布局中使用到了WebView这一控件,这个控件就是用来显示网页的。接着修改MainActivity中的代码
@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"); }获取到WebView控件实例后,调用WebView的getSettings()方法可以设置一些浏览器的属性,在这里我们就简单的调用setJavaScriptEnabled()方法让WebView支持JavaScript脚本。 接下来调用WebView的setWebViewClient()方法并传入一个WebViewClient的实例,这段代码的作用是,当需要从一个网页跳转到另一个网页时,我们希望目标网页仍然在当前WebView中显示,而不是打开系统浏览器。 最后调用WebView的loadUrl方法设置要访问的网页。由于我们用到了网络,因此需要在Manifest文件中声明网络权限。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.studio.webviewtest"> <uses-permission android:name="android.permission.INTERNET"></uses-permission> .... ....接着我们运行程序查看效果。
二、使用Http协议访问网络 使用Http协议访问网络的原理就是客户端向服务器发送一条Http请求,服务器收到请求之后会返回一些数据给客户端,然后客户端再对这些数据进行解析和处理就可以了。上一节的WebView控件实际上就已经在后台帮我们完成了发送Http请求、接收服务器返回的数据、解析返回的数据以及展示最终的页面这几步操作了。
1、使用HttpURLConnection 曾经Android上发送Http请求有两种方法,HttpClient和HttpURLConnection,不过HttpClient由于API数量过多在Android6.0后被废除了,因此在Android6.0后我们一般使用HttpURLConnection来发送Http请求。 首先我们需要获取到HttpURLConnection的实例,一般只需要new一个URL对象,并传入目标的网络地址,然后调用URL的openConnection()方法就可以得到了。
URL url=new URL("http://www.baidu.com"); HttpURLConnection connection=(HttpURLConnection) url.openConnection();得到了HttpURLConnection的实例后,我们需要设置Http请求所使用的方法,常用的方法有GET和POST。GET表示希望从服务器那里获取数据,POST表示希望提交数据给服务器,写法如下。
connection.setRequestMethod("GET");接下来就可以设置连接超时、读取超时的毫秒数,以及服务器希望得到的一些消息头等。
connection.setConnectionTimeout(8000); connection.setReadTimeout(8000);之后再调用HttpURLConnection的getInputStream()方法就可以得到服务器返回的输入流,剩下的任务就是对输入流进行读取。
InputStream in=connection.getInputStream();最后可以调用disconnect方法将Http连接关闭掉。
connection.disconnect();下面我们用一个实际例子展示,新建一个Android项目,修改activity_main.xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.studio.networktest.MainActivity"> <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>我们定义了一个Button用来发送Http请求,并且将返回的数据放在TextView中显示。接着修改MainActivity中的代码。
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button sendRequest; private TextView responseText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); 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(); } } private void sendRequestWithHttpURLConnection() { //开启子线程来发起耗时的网络请求 new Thread(new Runnable() { @Override public void run() { BufferedReader reader=null; HttpURLConnection connection=null; try { URL url=new URL("https://www.baidu.com"); connection= (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); InputStream in=connection.getInputStream(); //下面对获取的输入流进行读取 reader=new BufferedReader(new InputStreamReader(in)); StringBuilder response=new StringBuilder(); String line=null; while ((line=reader.readLine())!=null) { response.append(line); } showResponse(response.toString()); } catch (java.io.IOException 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); } }); } }这里需要注意的就是由于网络请求是耗时请求,因此我们需要将其放在子线程中执行;但是由于Android不允许在子线程中对UI进行操作,因此当我们要设置TextView的文本信息时需要通过runOnUiThread()方法切换到主线程再来更新文本信息。 运行程序,效果如下。 这些代码就是百度界面的源码,也就是服务器返回给客户端的数据,由于这次没有WebView来对返回的数据进行解析和显示,因此只会显示一堆源码。 注意不要忘了声明网络权限! 那么如果想利用Http协议提交数据给服务器要怎么办呢?只需要将Http请求的方法改为POST,并在获取输入流之前把要提交的数据写出即可。注意每条数据都要以键值对的形式存在,数据与数据之间用&隔开,比如我们想要向服务器提交用户名和密码:
connection.setRequestMethod("POST"); DataOutputStream out=new DataOutputStream(connection.getOutputStream); out.writeBytes("username=admin&password=123456");2、使用OkHttp 在开源库盛行的今天,有许多出色的网络通信库都能替代Android原生的HttpURLConnection,OkHttp就是其中之一,现在已经成为了Android开发者首选的网络通信库。 首先添加OkHttp库的依赖(截止这篇文章,Github官方的最新版本是OkHttp3.8.0)。
compile 'com.squareup.okhttp3:okhttp:3.8.0'下面我们来看一下OkHttp的具体用法,首先需要创建一个OkHttpClient的实例
OkHttpClient client=new OkHttpClient();接下来如果想发起一条Http请求,就需要创建一个Request对象
Request request=new Request.Builder().build();上述代码只是创建了一个空的Request对象,我们可以在最终的build()方法前连缀很多其他方法来丰富这个Request对象,比如可以通过url()方法来设置目标的网络地址
Request request=new Request.Builder().url("http://www.baidu.com").build();之后调用OkHttpClient的newCall()方法来创建一个Call对象,并调用它的execute()方法来发送请求并获取服务器返回的数据。
Response response=client.newCall(request).execute();其中Response对象就是服务器返回的数据封装类,我们可以使用如下写法来得到返回数据的具体内容。
String responseData=response.body().string();如果是发起一条POST请求会比GET请求复杂一些,我们需要先构建出一个RequestBody对象来存放待提交的参数
RequestBody requestBody=new FormBody.Builder().add("username","admin") .add("password","123456").build();然后在Request.Builder中调用一下post()方法,并将RequestBody对象传入
Request request=new Request.Builder().url("http://www.baidu.com") .post(requestBody).build();接下来的操作就和GET请求一样了,调用execute()方法来发送请求并获取服务器返回的数据即可。下面我们将之前的操作用OkHttp实现一遍
private void sendRequestWithOkHttp() { new Thread(new Runnable() { @Override public void run() { try { OkHttpClient client=new OkHttpClient(); Request request=new Request.Builder().url("http://www.baidu.com").build(); Response response=client.newCall(request).execute(); String responseData=response.body().string(); showResponse(responseData); } catch (IOException e) { e.printStackTrace(); } } }).start(); }可以看到用OkHttp的代码量比之前少了很多,这就是OkHttp的强大之处。
