安卓网络知识总结(三)--HTTPURLConnection总结

HTTPURLConnection总结

之前说过安卓网络一般都是http协议的,其实觉得工作原理就是客户端向服务器发一条请求,服务器收到这个请求就返回相应的东西,然后客户端解析就好了,再把解析的数据处理下。安卓有很多网络框架,但是实质上还是HTTPURLConnection为基础的东西,只不过就是他们封装的好一些,或者优化了不少。

HttpURLConnection的工作原理

Http协议工作原理特别的简单,就是客户端向服务器发出一条HTTP请求,服务器收到请求之后会返回一些数据给客户端,然后客户端再对这些数据进行解析和处理就可以了。
这里写图片描述
我们可以简单理解为,客户端发送一个URL,通过这个URL就可以找到服务器,然后服务器通过地址一看,就知道你要什么东西,就返回数据给你。

我们都知道计算式的所有数据是0和1的数据,这些数据我们可以想象成小水滴,小水滴的传输我们需要一个管道,从我们这里流出去的,叫做输出流,可从别人那里流过来的,叫做输入流
判断输入流还是输出流 :都是相对自身而言的。
安卓的耗时操作的逻辑不能写在主线程,必须写在子线程(I/O流操作肯定是耗时,肯定得写在子线程)
I/O流的简单操作//I就是input,O就是output

HttpURLConnection的工作过程

  • 得到URL
  • 开启连接
  • 声明是那种方式 是发送还是接收
  • 打开流
  • 对流进行操作
  • 关闭流
URL url = new URL(requestUrl); // 打开一个HttpURLConnection连接
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
// 设置连接主机超时时间
urlConn.setConnectTimeout(5 * 1000);
// 设置从主机读取数据超时
urlConn.setReadTimeout(5 * 1000);
// 设置是否使用缓存 默认是true
urlConn.setUseCaches(true); /
/ 设置为Post请求 urlConn.setRequestMethod("GET");
// urlConn设置请求头信息
// 设置请求中的媒体类型信息。
urlConn.setRequestProperty("Content-Type", "application/json");
// 设置客户端与服务连接类型 urlConn.addRequestProperty("Connection", "Keep-Alive");
// 开始连接 urlConn.connect();
// 判断请求是否成功 if (urlConn.getResponseCode() == 200)
{ // 获取返回的数据
String result = streamToString(urlConn.getInputStream());
Log.e(TAG, "Get方式请求成功,result--->" + result); }
else { Log.e(TAG, "Get方式请求失败"); }
// 关闭连接 urlConn.disconnect(); }
 catch (Exception e) 
}
 }

注意
1HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。 无论是post还是get,http请求实际上HttpURLConnection的getInputStream()这个函数里面才正式发送出去。

2在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重,对connection对象的一切配置(那一堆set函数) 都必须要在connect()函数执行之前完成。而对outputStream的写操作,又必须要在inputStream的读操作之前。这些顺序实际上是由http请求的格式决定的。

3http请求实际上由两部分组成,一个是http头,所有关于此次http请求的配置都在http头里面定义, 一个是正文content。connect()函数会根据HttpURLConnection对象的配置值生成http头部信息,因此在调用connect函数之前,就必须把所有的配置准备好。

4在http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的,实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络, 而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求 正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http 请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数 之后对connection对象进行设置(对http头的信息进行修改)或者写入outputStream(对正文进行修改)都是没有意义的了,执行这些操作会导致异常的发生。

简单的网络请求练习

就简单的输入URL在网上获取这张图片,然后放在app里面
效果图
这里写图片描述
这里写图片描述

第一步:打开网络权限//这个肯定是必须的啊
在res/androidManifest.xml里面添加权限
这里写图片描述
第二步:布局界面
这个也蛮简单的就是一个ImagView和EditText再加上一个Button

<?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:orientation="vertical"
    tools:context=".MainActivity">
    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"/>
    <EditText
        android:id="@+id/et_path"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入图片的路径"
        android:singleLine="true"/>
    <Button
        android:id="@+id/bt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="获取" />
</LinearLayout>

第三步:MainActivity
就是网络请求这块重新开个线程 然后用handler控制一下

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button bt;
    private ImageView show;
    private EditText et;
    private HttpURLConnection conn;
    private String path;
    private Bitmap bitmap;

    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if (msg.what==1){
                bitmap = (Bitmap)msg.obj;
                show.setImageBitmap(bitmap);
            }else if (msg.what==0){
                Toast.makeText(MainActivity.this,"失败",Toast.LENGTH_SHORT).show();
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et = (EditText) findViewById(R.id.et_path);
        show = (ImageView) findViewById(R.id.iv);
        bt = (Button) findViewById(R.id.bt);
        bt.setOnClickListener(this);
        et.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt:
                path = et.getText().toString().trim();
                //子线程网络请求
                Log.d("233","1");
                if (TextUtils.isEmpty(path)) {
                    Toast.makeText(MainActivity.this, "路径不为空", Toast.LENGTH_SHORT).show();
                } else {
                    sendConnection();
                    Log.d("233","1");
                }
        }
    }
    private void sendConnection(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                URL url;
                try {
                    url = new URL(path);
                    //打开连接
                    conn = (HttpURLConnection)url.openConnection();
                    //设置请求方式
                    conn.setRequestMethod("GET");
                    //超时时间
                    conn.setReadTimeout(5000);
                    //得到服务器的返回码
                    int code =conn.getResponseCode();
                    if (code==200){
                        //获取服务器的返回输入流
                        InputStream is = conn.getInputStream();
                        //转换成BIth对象
                        bitmap = BitmapFactory.decodeStream(is);
                        Message msg = new Message();
                        msg.what =1;
                        msg.obj=bitmap;
                        handler.sendMessage(msg);
                    }else {
                        Message message = new Message();
                        message.what = 0;
                        handler.sendMessage(message);
                    }
                    conn.disconnect();
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

总结

网络这块虽然以后用的别人的框架,但是最基础的还是要会的,就是一个简单的小Dome,最近自己要抓紧时间学习了哇哇哇,没时间了哇咔咔。
Dome的git地址https://github.com/sakurakid/HttpDome

猜你喜欢

转载自blog.csdn.net/sakurakider/article/details/80468235