您的位置:首页 > 理论基础 > 计算机网络

Android 开发实战 网络

2017-10-30 09:35 155 查看
一、重新学习一下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  建立,创建
             

     

  (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之间可以开始传输数据了。

 


示例下载一张图片并显示 在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 网络图片