android学习之网络图片查看器

首先,做这个小程序的时候是看的传智播客11年的视频,当时安卓只有2.2版本,而按照当时视频的代码敲打下来,发现程序根本无法与运行。

在这里给和我一样的新手们分享我做这个小程序的心得。

我在做这个程序的时候解决了2个比较关键的问题:

1.在调用HttpURLConnection类的 getResponseCode();方法的时候会返回一个android.os.NetworkOnMainThreadException异常

解决方法:android2.3的版本已经无法在主线程处理网络的请求了,于是,我们可以把获取网络图片的方法,放在Runnable的run方法中调用。

关键代码如下:

Thread t = new Thread(new Runnable() 
{
					
		@Override
		public void run() 
		{
			//service是获取网络图片的方法,strurl是url地址的字符串
			service(strurl);
		}
});
t.start();

2.但是当运行上面代码的时候,发现了当代码运行到service方法的时候,会抛出下面的异常

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

解决方法,在service前后作如下处理:

Thread t = new Thread(new Runnable() 
{
					
		@Override
		public void run() 
		{
			//service是获取网络图片的方法,strurl是url地址的字符串
                        Looper.prepare();
			service(strurl);
                        Looper.loop();
		}
});
t.start();

因为默认情况下Android中新诞生的线程是没有开启消息循环的.(主线程除外,主线程系统会自动为其创建Looper对象,开启消息循环)
Looper类别用来为一个线程开启一个消息循环,Looper对象通过MessageQueue来存放消息和事件.一个线程只能有一个Looper,对应一个MessageQueue.
关于Looper类和线程我会在文章结尾贴出2个相关链接供大家参考。
下面贴出我的代码和程序运行效果:

package com.ckp.webimage;

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

import com.ckp.imageservice.ImageService;

import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.StrictMode;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import android.os.Build;

public class MainActivity extends ActionBarActivity {

	
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		if (savedInstanceState == null) {
			getSupportFragmentManager().beginTransaction()
					.add(R.id.container, new PlaceholderFragment()).commit();
		}
		
	}

	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	/**
	 * A placeholder fragment containing a simple view.
	 */
	public static class PlaceholderFragment extends Fragment {

		Button bShow = null;
		ImageView imageview = null;
		EditText editUrl = null;
		
		public PlaceholderFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			View rootView = inflater.inflate(R.layout.fragment_main, container,
					false);
				
			return rootView;
		}

		@Override
		public void onActivityCreated(Bundle savedInstanceState) {
			// TODO Auto-generated method stub
			super.onActivityCreated(savedInstanceState);
			
			bShow = (Button) getView().findViewById(R.id.bShow);
			imageview = (ImageView) getView().findViewById(R.id.imageView1);
			editUrl = (EditText) getView().findViewById(R.id.editUrl);
			editUrl.setText("http://a.hiphotos.baidu.com/image/pic/item/f7246b600c338744ebc2527d530fd9f9d72aa0af.jpg");
			bShow.setOnClickListener(new ButtonListner());
			
		}

		//按钮响应处理
		private class ButtonListner implements View.OnClickListener
		{

			@Override
			public void onClick(View v) 
			{
				final String strurl = editUrl.getText().toString();
				
				Thread t = new Thread(new Runnable() {
					
					@Override
					public void run() {
						Looper.prepare();
						service(strurl);
						Looper.loop();
					}
				});
				t.start();		
			}
		}//onclick
			
		//把所有的网络操作的图片都放到这个方法里面,因为没有把各种可重用代码封装起来,看起来更清晰
		public void service(String strurl)
		{
			try {
						URL url = new URL(strurl);
						HttpURLConnection httpcon = (HttpURLConnection) url.openConnection();
						httpcon.setConnectTimeout(5000);
						httpcon.setReadTimeout(5000);
						httpcon.setRequestMethod("GET");
						
						if(httpcon.getResponseCode() == 200)
						{
							InputStream inStream = httpcon.getInputStream();
							
							byte[] buffer = new byte[1024];
							ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
							int len = 0 ;
							
							while((len = inStream.read(buffer))!= -1)
							{
								byteStream.write(buffer,0,len);
							}
							Bitmap bm = BitmapFactory.decodeByteArray(byteStream.toByteArray(), 0, byteStream.toByteArray().length);
							imageview.setImageBitmap(bm);
							
						}
					} 
					catch (Exception e) 
					{
						e.printStackTrace();
					}
		}
	
	}

}
以下是程序运行的效果图:


这个程序从出错到解决一共用了我2天的时间,分享这些代码和问题解决的方法希望能够帮助到更多像我这样的android学习新手
下面是2个对我问题解决帮助很大的资料链接:
http://blog.csdn.net/SamLee1989/article/details/8289631
http://blog.csdn.net/jackchen95/article/details/13631761


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值