webView 的用法
可以使用它在自己的程序中嵌入一个浏览器, 用来展示各种各样的网页
新建一个 WebVitwTest 项目, 修改 activity 中的代码
- <?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"
- >
- <WebView
- android:id="@+id/web_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
- </LinearLayout>
这里使用了 WebView 控件, 用来显示网页的, 让它充满全屏
修改 MainActivity 中的代码
- 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.setWebChromeClient(new WebChromeClient());
- webView.loadUrl("http://www.jianshu.com");
- }
- }
首先获取到了 WebVIew 的实例, 然后调用 getSettings() 方法去设置一些浏览器的熟悉, 这里只是调用了
setJavaScriptEnabled(true)
方法, 让 WebView 支持 javaAcript 脚本
接下来就是调用
setWebChromeClient()
方法, 并传入一个 WebViewClient 的实例, 就是当需要从一个网页跳到另一个网页时, 目标网页仍然是在当前的 WebView 中显示, 而不是打开系统的浏览器
最后就是调用 loadUrl() 方法, 并将网址出入就可以了
由于使用到了网络功能, 要访问网络是需要声明权限的, 还的 AndroidManifest 中的代码
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.md.web">
- <uses-permission android:name="android.permission.INTERNET"/>
- ...
- </manifest>
运行程序, 这个时候要确保模拟器是联网的就可以了
WebView 网页. png
当然了, 这只是一种简单的实现方式, 下面就是利用 Http 协议做真正的网络开发工作了
使用 HTTP 协议访问网络
上面使用 WebView 访问网页, 因为是封装好的, 不能直观的看出来 HTTP 协议到底是如何工作的, 下面通过手动方法 HTTP 请求的方法, 深入的了解一下这个过程
使用 HttpURLConnection
首先获取到 HttpURLConnection 的实例, 只需 new 出一个 URL 对象, 并传入目标的网络地址中, 然后调用一下 openConnection() 方法即可
- URL url = new URL("http://www.baidu.com");
- HttpURLConnection connection = (HttpURLConnection)url.openConnection();
获取到实例后, 设置一下 HTTP 请求所使用的方法, 常用的就是 POST 和 GEE 请求, GET 就是从服务器那获取数据, POST 请求就是提交数据给服务器
connection.setRequestMethod("GET")
下面就是自由的定制了, 比如设置连接超时, 读取超时的毫秒数, 以及服务器希望得到的一些消息头等
- connection.setConnecTimeout(8000);
- connection.setReadTImeout(8000);
之后调用 getInputStream() 方法读取到服务器返回的输入流就可以,
InputStream in = connection.getInputStream();
最后调用 disconnect() 方法将这个 HTTP 连接关闭就可以了
新建一个 NetworkTest 项目, 进行实际操作一下, 修改 activity 中的代码
- <?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"
- />
- <ScrollView
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <TextView
- android:id="@+id/request_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- </ScrollView>
- </LinearLayout>
这里使用了新的控件 ScrollView, 就是可以借助滚动的形式查看屏幕以外的部分内容, Button 用于发送 HTTP 请求, TextView 用于将服务器返回的数据显示
修改 MainActivity 中的代码
- public class MainActivity extends AppCompatActivity implements View.OnClickListener{
- private TextView responseText;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- Button sendRequst = (Button)findViewById(R.id.send_request);
- responseText = (TextView)findViewById(R.id.request_text);
- // 按钮添加绑定事件
- sendRequst.setOnClickListener(this);
- }
- @Override
- public void onClick(View view) {
- if (view.getId() == R.id.send_request){
- sendRequestWithHttpURLConnection();
- }
- }
- private void sendRequestWithHttpURLConnection(){
- // 开启线程来发送网络请求
- new Thread(new Runnable() {
- @Override
- public void run() {
- HttpURLConnection connection = null;
- BufferedReader reader = null;
- try {
- // 获取到实例
- URL url = new URL("https://www.jianshu.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;
- 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() {
- // 这里拿数据显示到界面上
- responseText.setText(response);
- }
- });
- }
- }
首先在按钮的点击事件中调用了 sendRequestWithHttpURLConnection() 方法
这个方法中先是开启了一个子线程, 在子线程中使用了 HttpURLConnection 发送了一个 HTTP 请求, 请求的是简书首页, 利用 BufferedReader 对服务器返回的流进行读取, 然后把数据传入到 showResponse() 方法中
在这个方法中, 使用了 runOnUiThread() 方法, 把数据设置到 textView 中, 为什么使用这个 runOnUiThread() 方法, 是因为 Android 是不允许在子线程中进行 UI 操作的, 通过这个方法将线程切换到主线程
当然了, 最后还得声明一下网络权限, 在 AndroidManifest 中
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.md.web">
- <uses-permission android:name="android.permission.INTERNET"/>
- ...
- </manifest>
运行程序, 点击按钮就可以了
返回的数据. png
返回的是源码,
如果是想要给服务器提交数据怎么办, 这个时候把请求方式改成 GET 请求就可以了, 并在获取输入流之前把要提交的数据写入就可以了, 注意每条数据都要用键值对的形式, 数据之间使用 & 号区分就可以了, 比如提交用户名和密码
- connection.setRequestMethod("POST");
- DataOutputStream out = new DataOutputStream(connection.getOutputStream());
- out.writeBytes("username=pony007&&password=123456");
使用 OkHttp
添加 OkHttp 库的依赖, 编辑 app/build.gradle 文件, 在 dependencies 闭包中
- dependencies {
- ...
- compile 'com.squareup.okhttp3:okhttp:3.4.1'
- }
OkHttp 的基本用法
创建一个 OkHttpClient 的实例
OkHttpClient client = new OkHttpClient()
接下来如果想要发送一条 HTTP 请求, 就需要创建一个 Request 对象
Request request = new Request.Builder().build();
当然了, 这只是一个空的 Rerquest 对象, 没有实际的作用, 在最终的 build() 方法之前连缀很多其他方法来丰富这个 Request 对象, 比如可以通过 url() 方法来设置目标网络地址
- .url("https://www.jianshu.com/")
- .build();
之后调用 OkHttpClient 的 newCall() 方法来创建一个 Call 对象, 并调用它的 execute() 方法来发送请求并获得服务器返回的数据
Response response = client.newCall(request).execute();
其中的 Request 对象就是服务器返回的数据, 可以使用下面的写法来得到返回的具体内容
String responseData = response.body().string();
如果是 POST 请求会比 GET 请求稍微复杂一点, 首先构建一个 RequestBody 对象用来存放待提交的数据, 如下
- RequestBody requestBody = new FormBody.Builder()
- .add("username","pony007")
- .add("password","123456")
- .build();
然后在 Request.Builder 中调用 post() 方法并将 RequestBody 对象传入
- .url("https://www.jianshu.com/")
- .post(requestBody)
- .build();
接下来就是和 GET 请求一样了, 调用 execute() 方法获取返回的数据就可以了
继续改上面的程序, 布局的就不用改动了, 直接该 MainActivity 中的, 添加一个 sendRequestWithOkHttp() 方法就可以了
- public class MainActivity extends AppCompatActivity implements View.OnClickListener{
- private TextView responseText;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- Button sendRequst = (Button)findViewById(R.id.send_request);
- responseText = (TextView)findViewById(R.id.request_text);
- // 按钮添加绑定事件
- sendRequst.setOnClickListener(this);
- }
- @Override
- public void onClick(View view) {
- if (view.getId() == R.id.send_request){
- sendRequestWithOkHttp();
- }
- }
- private void sendRequestWithOkHttp(){
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- OkHttpClient client = new OkHttpClient();
- Request request = new Request.Builder()
- .url("https://www.jianshu.com/")
- .build();
- Response response = client.newCall(request).execute();
- // 获取到了从服务器返回的数据
- String responseData = response.body().string();
- // 把获取的数据传入到这个方法中
- showResponse(responseData);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- }
- private void showResponse(final String response){
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- // 这里拿数据显示到界面上
- responseText.setText(response);
- }
- });
- }
- }
在这个方法中还是开启了一个子线程, 使用 OkHttp 发出一条 HTTP 请求, 最后还是使用 showResponse() 方法将服务器返回的数据显示在界面上了
可以看到这个非常的简便, 实现的功能是一样的
OkHttp 返回的数据. png
来源: http://www.jianshu.com/p/9da6e9e7a5f9