前段时间看到一个数据,据说中国网民数量已经达到7亿多,看到这个数字就尿了,现在连小学生玩微信都啪啪啪的6,作为移动应用开发者,你的APP要是没有联网功能的话那就太low了,当然要让APP进行一些网络请求也不是扫码难事,今天咱就来一起加载一个网络图片玩玩。

首先你要准备一张用于加载的网络图片,取到它的网络地址,当然为了方便,我用Tomcat在本地搭建了一个web服务器,把它运行,图片放到我web服务器的根目录下。

android 加载res图片_图片

服务器启动以后,在我的浏览器访问图片。

android 加载res图片_图片_02

OK,是可以访问的,我的图片就是放在上边那个地址所对应的服务器位置里,它就是一个网络图片,当然你可以从网上找你喜欢的图片地址。

准备工作做好以后,下面就要在安卓应用中去请求网络加载它了。

我在创建好安卓工程后,制作了下面这样的布局,很简单,就是一个Button,下面还有一个ImageView。

android 加载res图片_android 加载res图片_03

接着就是在Activity里声明初始和化View控件了


private ImageView iv_downpic_main;



我给按钮单独设置了一个点击方法


public void downPic (View v) {
<span style="white-space:pre">	</span>//图片的网络path路径
<span style="white-space:pre">	String path = "http://192.168.0.109:8080/cool_man.jpg";</span>
<span style="white-space:pre">	</span>//声明一个连接对象
<span style="white-space:pre">	HttpURLConnection conn = null;
	//声明一个输入流</span>
<span style="white-space:pre">	InputStream is = null;
<span style="white-space:pre">		</span>    <span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>try {
<span style="white-space:pre">		</span>URL url = new URL(path);</span>
<span style="white-space:pre"><span style="white-space:pre">		</span>//打开url连接
<span style="white-space:pre">		</span>conn = (HttpURLConnection) url.openConnection();</span>
<span style="white-space:pre"><span style="white-space:pre">		</span>//设置请求方式为GET
<span style="white-space:pre">		</span>conn.setRequestMethod("GET");</span>
<span style="white-space:pre"><span style="white-space:pre">		</span>//设置连接超时时间为5秒
<span style="white-space:pre">		</span>conn.setConnectTimeout(5000);</span>
<span style="white-space:pre"><span style="white-space:pre">		</span>//设置读取超时时间为5秒
<span style="white-space:pre">		</span>conn.setReadTimeout(5000);</span>
<span style="white-space:pre"><span style="white-space:pre">		</span>//建立连接
<span style="white-space:pre">		</span>conn.connect();
<span style="white-space:pre">		//如果返回的请求码为200的话	</span>
<span style="white-space:pre">		</span>if(conn.getResponseCode() == 200){</span>
<span style="white-space:pre"><span style="white-space:pre">			</span>//得到一个连接输入流
<span style="white-space:pre">		<span style="white-space:pre">	</span></span>is = conn.getInputStream();</span>
<span style="white-space:pre"><span style="white-space:pre">			</span>//用bitmap读取输入流
<span style="white-space:pre">		<span style="white-space:pre">	</span></span>bitmap = BitmapFactory.decodeStream(is);</span>
<span style="white-space:pre"><span style="white-space:pre">			</span>//设置图片为bitmap读取到的图片
<span style="white-space:pre">		<span style="white-space:pre">	</span></span>iv_downpic_main.setImageBitmap(bitmap);
<span style="white-space:pre">						</span>
<span style="white-space:pre">		</span>} else {</span>
<span style="white-space:pre"><span style="white-space:pre">			</span>//请求码不为200的话,toast提示请求失败
<span style="white-space:pre">		<span style="white-space:pre">	</span></span>Log.e("TAG", "请求失败!");//
<span style="white-space:pre">		<span style="white-space:pre">	</span></span>Toast.makeText(MainActivity.this, "请求失败!", 0).show();
<span style="white-space:pre">						</span>
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>} catch (Exception e) {
<span style="white-space:pre">		</span>// TODO Auto-generated catch block
<span style="white-space:pre">		</span>e.printStackTrace();
<span style="white-space:pre">	</span>}finally{
<span style="white-space:pre">		</span>if(conn != null){</span>
<span style="white-space:pre"><span style="white-space:pre">			</span>//关闭连接
<span style="white-space:pre">			</span>conn.disconnect();
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>if(is != null){
<span style="white-space:pre">			</span>try {</span>
<span style="white-space:pre"><span style="white-space:pre">				</span>//关闭输入流
<span style="white-space:pre">				</span>is.close();
<span style="white-space:pre">			</span>} catch (IOException e) {
<span style="white-space:pre">				</span>// TODO Auto-generated catch block
<span style="white-space:pre">				</span>e.printStackTrace();
<span style="white-space:pre">			</span>}
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>}</span>
</pre><pre name="code" class="java">
}

这样的方法在安卓4.0之前是行的通的,然而在安卓4.0以后,这些代码就不好使了,为避免ANR的产生,程序在进行联网等耗时操作时是禁止在主线程里执行的。

改进的做法是,把联网获取图片的操作拿到分线程去执行,然而跟新UI界面的操作用Handler在主线程进行UI跟新。


public class MainActivity extends Activity {
	private static final int WHAT_DAWNLOAD_PICTURE = 0;
	protected static final int WAHT_TOAST = 1;
	private ImageView iv_downpic_main;
	private Bitmap bitmap;
	private Handler handler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case 0:
				iv_downpic_main.setImageBitmap(bitmap);
				break;
			case 1 :
				Toast.makeText(MainActivity.this, "请求失败!", 0).show();
				break;
			default:
				break;
			}
		};
	};
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        iv_downpic_main = (ImageView) findViewById(R.id.iv_downpic_main);
    }
    
    public void downPic (View v) {
    	final String path = "http://192.168.0.109:8080/cool_man.jpg";
    	new Thread(new Runnable() {
			
			@Override
			public void run() {
				HttpURLConnection conn = null;
		    	InputStream is = null;
		    	
		    	try {
					URL url = new URL(path);
					conn = (HttpURLConnection) url.openConnection();
					conn.setRequestMethod("GET");
					conn.setConnectTimeout(5000);
					conn.setReadTimeout(5000);
					conn.connect();
					
					if(conn.getResponseCode() == 200){
						is = conn.getInputStream();
						bitmap = BitmapFactory.decodeStream(is);
						handler.sendEmptyMessage(WHAT_DAWNLOAD_PICTURE);
						
					} else {
						Log.e("TAG", "请求失败!");//
						handler.sendEmptyMessage(WAHT_TOAST);
						
					}
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally{
					if(conn != null){
						conn.disconnect();
					}
					if(is != null){
						try {
							is.close();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			}
		}).start();
    	
    }

}

这里要说的是,Toast提示信息也需要在主线程进行跟新,如果单独把它放在分线程执行的话,是么有效果的,而且后台也会报错:

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()


代码写好以后,就运行测试吧。

点击按钮把酷男显示出来。


效果还不错!