一、重新学习一下HTTP协议

定义:万维网是以internet 作为传输媒介的一个应用系统,万维网上最基本的传输单位是Web网页。万维网的工作基于客户机/服务器(CS)计算机模型,由Web浏览器(客户机)和web 服务器 构成,两者之间采用超文本传输协议(HTTP)进行通信。HTTP协议是基于TCP/IP协议之上的协议,是web浏览器和web服务器之间的应用层协议,是通用的、无状态的、面向对象的协议,从而可以通过HTTP协议进行网络互联。

Internet 内部通过三种形式实现数据的发送与接收:

1.HTTP协议,工作总最常用的,建立在TCP/IP的基础上实现的。

2.FTP协议

3.TCP/IP协议,它是最底层的协议其他的方式必须要通过它来实现通信,但是要想实现这种协议就必须要事件socket 编程,然而socket 编程又分为客户端和服务端,服务端的任务就是要监听某一段口,接受客户端端连接,客户端一旦连接到服务端,就会以流的方式发送数据,但是这种做法是用来上传一些大的文件、视频、断点续传等。

         tcp标志位,有6种标示:

           SYN(synchronous建立联机)

           ACK(acknowledgement 确认)

           PSH(push传送)

           FIN(finish结束)

           RST(reset重置)

           URG(urgent紧急)

           Sequence number(顺序号码)

           Acknowledge number(确认号码) 

           establish  建立,创建

              Android 开发实战 网络

     

  (1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

 

  (2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack (number )=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态

 

  (3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

 Android 开发实战 网络


示例下载一张图片并显示 在ImageView上

代码如下:

 activity_main.xml

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.kangxg.network.MainActivity">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="80dp"
            android:id="@+id/textTitle"
            android:text="@string/path"/>
        <EditText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="http://www.kangxg.cn/image/g_0.jpg"
            android:layout_below="@id/textTitle"
            android:layout_centerHorizontal="true"
            android:id="@+id/path"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/button"
            android:id="@+id/TButton"
            android:layout_below="@id/path"
            android:layout_centerHorizontal="true"/>
        <ImageView
            android:layout_width="250dp"
            android:layout_height="250dp"
            android:layout_below="@id/TButton"
            android:layout_centerHorizontal="true"
            android:background="@android:color/holo_red_dark"
            android:id="@+id/TImageView"/>

    </RelativeLayout>

 MainActivity.java
  
public class MainActivity extends AppCompatActivity implements OnClickListener{
    private static final String TAG = "TActivity";
    private EditText    imageEditText;
    private ImageView   imageView;
    private  AsyncLoadHandler     handler  = new AsyncLoadHandler() ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageEditText = (EditText)findViewById(R.id.path);
        imageView     = (ImageView)findViewById(R.id.TImageView);
      
        Button button = (Button)findViewById(R.id.TButton);
        button.setOnClickListener(this);
    }

    @Override
    public void  onClick(View v)
    {
        // 定义后台下载线程
        new Thread(new MyThread()).start();

    }

    class MyThread implements Runnable {

        @Override
        public void run() {
            Bitmap bitmap = null;
            String path = imageEditText.getText().toString();
            try {
               //URL url = new URL(path);//创建Url对象
               //InputStream inputStream = url.openStream();
                //bitmap = BitmapFactory.decodeStream(inputStream);

                byte[] data = NetTool.getImage(path);
                bitmap = BitmapFactory.decodeByteArray(data,0,data.length);

            } catch (Exception e) {

                e.printStackTrace();
                Log.i(TAG,e.getMessage());
                Toast.makeText(MainActivity.this,"获取图片失败",1).show();
            }
         //创建Message对象,返回信息
            Message message = Message.obtain();
            message.obj = bitmap;
            message.what = 1;
            handler.sendMessage(message);
        }

    }

    // 图片下载完成通知主线程显示图片
    public class AsyncLoadHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1) {
                Bitmap bitmap = (Bitmap) msg.obj;
                imageView.setImageBitmap(bitmap);

            }
        }
    }

}

Nettoll.java
  
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class NetTool {
    public  static byte[] getImage(String path) throws  Exception{
        URL url = new URL(path);
        HttpURLConnection conn  = (HttpURLConnection)url.openConnection();
        conn.setRequestMethod("GET");
        conn.setConnectTimeout(6*1000);
        if (conn.getResponseCode() == 200)
        {
            InputStream inputStream = conn.getInputStream();
            return  readInstream(inputStream);
        }
        return null;
    }

    public  static  byte[] readInstream(InputStream inputStream) throws Exception
    {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length = -1;
        while ((length = inputStream.read(buffer)) !=-1)
        {
            byteArrayOutputStream.write(buffer,0,length);
        }
        byteArrayOutputStream.close();
        inputStream.close();
        return byteArrayOutputStream.toByteArray();
    }
}

debug 运行
 

错误信息

解决办法在AndroidMainfest.xml 中添加
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
Android 开发实战 网络

再次运行后
Android 开发实战 网络

完毕!
总结:图片的下载 不能在主线程中操作,必须放在自线程中操作,下载完成后,主线程中操作完成!






相关文章: