Android学习--网络通信之网络图片查看器
笔记摘要:
这里主要讲IO流和Web技术相结合,由客户端提交获取图片服务请求,服务端返回图片。
同样的我们可以获取到各种格式的数据(文本、网页、XML、Json),只要在读取工具类中对数据进行相应的转换,返回指定格式的数据即可
需要注意的是:测试时访问路径不能使用localhost,必须使用IP地址,因为Android也是操作系统,所以它会认为是访问了自己系统的本地,就无法访问到资源
一、设计步骤
1、页面设计
注意:获得网络访问许可
2、创建一个web服务
在WebContent中存入一幅图片:a.jpg
3、编写图片服务类
一个工具类提供读取数据的方法
二、访问效果页面
三、代码实现
<RelativeLayout 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" > <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" tools:context=".MainActivity" /> <TextView android:id="@+id/textView1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/imagepath" /> <EditText android:id="@+id/imagepath" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/textView1" android:ems="10" android:text="http://192.168.1.106:8080/web/a.jpg" > <requestFocus /> </EditText> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/imagepath" android:layout_marginTop="21dp" android:text="@string/button" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/button" android:id="@+id/imageView" /> </RelativeLayout>
strings.xml
<resources> <string name="app_name">myNetPic</string> <string name="menu_settings">Settings</string> <string name="title_activity_main">MainActivity</string> <string name="imagepath">网络图片路径</string> <string name="button">查看</string> <string name="error">获取图片失败</string> </resources>
<!-- 访问Internet权限 --> <uses-permission android:name="android.permission.INTERNET"/>
MainActivity.java
package com.example.mynetpic; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.Toast; import com.example.service.ImageService; public class MainActivity extends Activity { private EditText pathText; private ImageView imageView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); pathText = (EditText)this.findViewById(R.id.imagepath); Button button = (Button)this.findViewById(R.id.button); imageView = (ImageView)this.findViewById(R.id.imageView); button.setOnClickListener(new ButtonClickListener()); } private final class ButtonClickListener implements View.OnClickListener{ public void onClick(View v) { String path = pathText.getText().toString();//获取文本框中的图片路径 try { byte[] data = ImageService.getImage(path);//调用ImageService工具类中的获取图片的方法 Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);//采用二进制来构建图片的位图数据 imageView.setImageBitmap(bitmap);//显示图片 } catch (Exception e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), R.string.error, 1).show();//获取失败,提示错误信息 } } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }
提供图片服务的工具类
package com.example.service; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import com.example.util.StreamTool; public class ImageService { /* *获取网络图片的数据 *@param path 网络图片路径 *@return * */ public static byte[] getImage(String path)throws Exception{ URL url = new URL(path);//将路径封装成URL对象 HttpURLConnection conn = (HttpURLConnection) url.openConnection();//得到一个基于HTTP协议的链接对象 conn.setConnectTimeout(5000);//设置请求时间为5秒 conn.setRequestMethod("GET");//请求方式为GET if(conn.getResponseCode() == 200){ //通过服务器的返回码,判断请求是否成功 InputStream inStream = conn.getInputStream();//获取输入流 System.out.println("ImageService"); return StreamTool.read(inStream); //这里将读取数据的方法单独抽取,提高重用性 } return null; } }
由于要反复读取数据,所以将读取数据的代码封装为一个工具类
package com.example.util; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; /* 读取流中的数据 @return * */ public class StreamTool { public static byte[] read(InputStream inStream) throws Exception{ ByteArrayOutputStream outStream = new ByteArrayOutputStream();//创建一个内存输出流,存放数据 byte[] buf = new byte[1024]; int len = 0; while((len = inStream.read(buf))!=-1){ //不断读取 outStream.write(buf,0,len); } inStream.close(); return outStream.toByteArray();//返回内存中的数据 } }