Android中用URL模拟一个简单的图片加载器
首先,需要添加权限。
<uses-permission android:name="android.permission.INTERNET"/>
整体代码如下:
package com.tarena.viewer; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; /** * 网络图片查看器,需要添加Internet权限 * @author chenchi * */ public class MainActivity extends Activity implements OnClickListener { Handler handler = new Handler(){ //处理消息的时候我们需要区分这是成功的消息还是失败的消息 //此方法在主线程中调用,可以用来刷新UI public void handleMessage(android.os.Message msg) { switch (msg.what) { case 1: ImageView imageView = (ImageView) findViewById(R.id.image_view); imageView.setImageBitmap((Bitmap) msg.obj); break; case 2: Toast.makeText(MainActivity.this, "加载失败", Toast.LENGTH_SHORT).show(); break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn_download = (Button) findViewById(R.id.btn_download); btn_download.setOnClickListener(this); } @Override public void onClick(View v) { Thread thread = new Thread(new Runnable() { @Override public void run() { //下载图片 //1.确定网址 String path = "http://192.168.31.225:8088/user.png"; try { //2.把网址封装成一个URL对象 URL url = new URL(path); //3.获取客户端和服务器的连接对象,此时还没有建立连接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //4.对连接对象进行初始化 //设置请求方法,注意大写 conn.setRequestMethod("GET"); //设置连接超时 conn.setConnectTimeout(10000); //设置读取超时 conn.setReadTimeout(10000); //5.发送请求,与服务器建立连接 conn.connect(); //如果响应码为200,说明请求成功 if(conn.getResponseCode() == 200){ //获取服务器响应头中的流,流里的数据就是客户端啊请求的数据 InputStream is = conn.getInputStream(); //读取出流里面的数据,并构造成位图对象 Bitmap bm = BitmapFactory.decodeStream(is); /* * 这两行代码为什么注释,是因为运行也没有结果的 * 因为只有主线程才能刷新UI操作,子线程是不可以的 */ // ImageView imageView = (ImageView) findViewById(R.id.image_view); // imageView.setImageBitmap(bm); //把消息返送到主线程的消息队列 Message msg = new Message(); //消息对象可以携带数据 msg.obj = bm; msg.what = 1; //成功加载消息,返回1 handler.sendMessage(msg); }else{ Message msg = handler.obtainMessage();//这样获取message是在池中获取,减少内存负荷 msg.what = 2;//失败加载消息,返回0 handler.sendMessage(msg); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }); thread.start(); } }
还可以继续加上缓存的功能。
package com.tarena.viewer; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import android.R.integer; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; /** * 网络图片查看器,需要添加Internet权限 * @author chenchi * */ public class MainActivity extends Activity implements OnClickListener { private String getFilesName(String path) { int index = path.lastIndexOf("/"); return path.substring(index + 1); } Handler handler = new Handler(){ //处理消息的时候我们需要区分这是成功的消息还是失败的消息 //此方法在主线程中调用,可以用来刷新UI public void handleMessage(android.os.Message msg) { switch (msg.what) { case 1: ImageView imageView = (ImageView) findViewById(R.id.image_view); imageView.setImageBitmap((Bitmap) msg.obj); break; case 2: Toast.makeText(MainActivity.this, "加载失败", Toast.LENGTH_SHORT).show(); break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn_download = (Button) findViewById(R.id.btn_download); btn_download.setOnClickListener(this); } @Override public void onClick(View v) { //下载图片 //1.确定网址 final String path = "http://192.168.31.225:8088/user.png"; //读取数据库返回的流里的数据,把数据写到本地文件,缓存起来 final File file = new File(getCacheDir(), getFilesName(path)); //判断,缓存中是否存在该文件 if(file.exists()){ //如果缓存存在,从缓存中读取数据 System.out.println("从缓存读取的"); Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath()); ImageView imageView = (ImageView) findViewById(R.id.image_view); imageView.setImageBitmap(bm); return; } System.out.println("从网络下载的"); Thread thread = new Thread(new Runnable() { @Override public void run() { try { //2.把网址封装成一个URL对象 URL url = new URL(path); //3.获取客户端和服务器的连接对象,此时还没有建立连接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //4.对连接对象进行初始化 //设置请求方法,注意大写 conn.setRequestMethod("GET"); //设置连接超时 conn.setConnectTimeout(10000); //设置读取超时 conn.setReadTimeout(10000); //5.发送请求,与服务器建立连接 conn.connect(); //如果响应码为200,说明请求成功 if(conn.getResponseCode() == 200){ //获取服务器响应头中的流,流里的数据就是客户端啊请求的数据 InputStream is = conn.getInputStream(); byte[] b = new byte[1024]; FileOutputStream fos = new FileOutputStream(file); int len = -1; while((len = is.read(b)) != -1){ fos.write(b, 0, len); } //读取出流里面的数据,并构造成位图对象 //Bitmap bm = BitmapFactory.decodeStream(is); Bitmap bm = BitmapFactory.decodeFile(file.getAbsolutePath()); /* * 这两行代码为什么注释,是因为运行也没有结果的 * 因为只有主线程才能刷新UI操作,子线程是不可以的 */ // ImageView imageView = (ImageView) findViewById(R.id.image_view); // imageView.setImageBitmap(bm); //把消息返送到主线程的消息队列 Message msg = new Message(); //消息对象可以携带数据 msg.obj = bm; msg.what = 1; //成功加载消息,返回1 handler.sendMessage(msg); }else{ Message msg = handler.obtainMessage();//这样获取message是在池中获取,减少内存负荷 msg.what = 2;//失败加载消息,返回0 handler.sendMessage(msg); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }); thread.start(); } }