Android -- 网络图片查看器,网络html查看器, 消息机制, 消息队列,线程间通讯

1. 原理图

 

2. 示例代码 (网络图片查看器)

(1)  HttpURLConnection

(2) SmartImageView (开源框架:https://github.com/loopj/android-smart-image-view

Handler 类, 消息队列处理

访问互联网需要权限

<uses-permission android:name="android.permission.INTERNET"/>

布局

<LinearLayout 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" 
    android:orientation="vertical" 
    tools:context=".MainActivity" >
    
    <ImageView android:id="@+id/iv_image"
        android:layout_weight="100"
        android:layout_width="match_parent"
    	android:layout_height="0dp" />
    
    <EditText android:id="@+id/et_path"
        android:layout_width="match_parent"
    	android:layout_height="wrap_content"
    	android:text="@string/link"
    	android:hint="输入网络链接" />
    
   	<Button android:id="@+id/bt_link"
   	    android:onClick="click"
   	    android:layout_width="match_parent"
    	android:layout_height="wrap_content"
    	android:text="查看" />
    	
</LinearLayout>

MainActivity.java

package com.kevin.netimageview;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import javax.net.ssl.HttpsURLConnection;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity {

	protected static final int CHANGE_UI = 0;
	protected static final int ERROR = 1;
	protected static final int LINK = 2;
	private EditText et_path;
	private ImageView iv_image;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		et_path = (EditText) findViewById(R.id.et_path);
		iv_image = (ImageView) findViewById(R.id.iv_image);
	}
	
	private Handler handler = new Handler(){
		@Override
		public void handleMessage(Message msg){ //消息处理
			if(msg.what==CHANGE_UI){
				Toast.makeText(getApplicationContext(), "CHANGE_UI", Toast.LENGTH_SHORT).show();				
				Bitmap bitmap = (Bitmap) msg.obj;
				iv_image.setImageBitmap(bitmap);
			}else if(msg.what==ERROR){
				Toast.makeText(getApplicationContext(), "发生ERROR", Toast.LENGTH_SHORT).show();			
			}
			else if(msg.what==LINK){
				Toast.makeText(getApplicationContext(), "将要获取响应", Toast.LENGTH_SHORT).show();				
			}
		} 
	};
	
	public void click(View v){			
		new Thread(){
			public void run(){
				
				String path = et_path.getText().toString().trim();
				if(path==null || path.length()==0){					
					Message msg = new Message();
					msg.what = ERROR;					
					handler.sendMessage(msg);
					return;
				}
				
				System.out.println("xxxxx");
				try {
					URL url = new URL(path);
					HttpURLConnection conn = (HttpURLConnection) url.openConnection();
					// 设置请求方式 为 GET
					conn.setRequestMethod("GET");
					// 设置请求超时时间
					conn.setConnectTimeout(5000);
					// 注意: 下面的读取超时的时间.
					// conn.setReadTimeout(timeoutMillis);
					conn.setRequestProperty(
							"User-Agent",
							"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727)");
					Message msg = new Message();
					msg.what = LINK;					
					handler.sendMessage(msg);
					// 把get请求发送出去,获取服务器上的数据
					// 获取服务器的返回码 状态码
					int code = conn.getResponseCode();
					if(code == 200){
						InputStream is = conn.getInputStream();
						Bitmap bitMap = BitmapFactory.decodeStream(is);
						msg = new Message();
						msg.what = CHANGE_UI;
						msg.obj = bitMap;
						handler.sendMessage(msg); //发送消息
					}
					
				} catch (Exception e) {
					e.printStackTrace();
					Message msg = new Message();
					msg.what = ERROR;					
					handler.sendMessage(msg);  //发送消息
				}
			}
		}.start();		
	}
}


可输入的参考URL: http://d.hiphotos.baidu.com/image/w%3D310/sign=07ccb79279cb0a4685228d385b62f63e/902397dda144ad3452bdd2efd2a20cf431ad8553.jpg 

 

(2)SmartImageView 使用开源框架

main.xml 布局文件ImageView 改成 SmartImageView即可, 需要引用类的全路径

<LinearLayout 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" 
    android:orientation="vertical" 
    tools:context=".MainActivity" >
    
    <com.loopj.android.image.SmartImageView android:id="@+id/siv_image"
        android:layout_weight="100"
        android:layout_width="match_parent"
    	android:layout_height="0dp" />
    
    <EditText android:id="@+id/set_path"
        android:layout_width="match_parent"
    	android:layout_height="wrap_content"
    	android:text="@string/link"
    	android:hint="输入网络链接" />
    
   	<Button android:id="@+id/sbt_link"
   	    android:onClick="click2"
   	    android:layout_width="match_parent"
    	android:layout_height="wrap_content"
    	android:text="查看" />
    	
</LinearLayout>

MainActivity.java中直接操作 SmartImageView即可,

public void click2(View v){
		SmartImageView iv_image =  (SmartImageView) findViewById(R.id.siv_image);
		String url = et_path.getText().toString().trim();
		//可以加入两张图片,分别在loading和获取文件失败的时候显示出来
		iv_image.setImageUrl(url, R.drawable.ic_launcher, R.drawable.ic_launcher);
		Toast.makeText(this, "显示网络图片", Toast.LENGTH_SHORT).show();
	} 

 

3. 示例代码 (网络html查看器)

原理和2的代码相似, 不过要注意乱码问题的处理

MainActivity.java

public class MainActivity extends Activity {
	protected static final int PATH_CANOT_NULL = 1;
	protected static final int GET_HTML_ERROR = 2;
	protected static final int SET_TEXT = 3;
	private TextView tv_content;
	private EditText et_path;
	
	//在主线程创建一个消息处理器
	private Handler handler = new Handler(){
		//当解析到新的消息时候的处理方法
		@Override
		public void handleMessage(Message msg) {
			//当有新的消息到来时候的处理方法
			switch (msg.what) {
			case PATH_CANOT_NULL:
				Toast.makeText(getApplicationContext(), "路径不能为空", 1).show();
				break;
			case GET_HTML_ERROR:
				Toast.makeText(getApplicationContext(), "获取html失败", 1).show();
				break;
			case SET_TEXT:
				String text = (String) msg.obj;//重新获取到消息对象里面的文本
				tv_content.setText(text);
				break;
			}
			super.handleMessage(msg);
		}
		
	};

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

		tv_content = (TextView) findViewById(R.id.tv_content);
		et_path = (EditText) findViewById(R.id.et_path);
	}

	public void viewHtml(View view) {
		//子线程
		new Thread() {
			public void run() {
				String path = et_path.getText().toString().trim();
				if (TextUtils.isEmpty(path)) {
					//Toast.makeText(MainActivity.this, "路径不能为空", 1).show();
					System.out.println("路径不能为空");
					Message msg = new Message();
					msg.what = PATH_CANOT_NULL; //指定消息的类型 一般用一个int类型的数据 区分不同的消息
					handler.sendMessage(msg);
					return;
				}
				try {
					URL url = new URL(path);
					HttpURLConnection conn = (HttpURLConnection) url
							.openConnection();
					conn.setRequestMethod("GET");
					conn.setConnectTimeout(5000);
					Thread.sleep(5000);// 模拟一个网络访问的延迟
					int code = conn.getResponseCode();
					if (code == 200) {
						InputStream is = conn.getInputStream();
						String text = StreamTools.readFromStream(is);
						//tv_content.setText(text);
						Message msg = new Message();
						msg.what = SET_TEXT; //指定消息的类型 一般用一个int类型的数据 区分不同的消息
						msg.obj = text;//把要传递的数据 放在这个消息里面
						handler.sendMessage(msg);
						
						
						
					} else {
						//Toast.makeText(MainActivity.this, "获取html失败", 0).show();
						System.out.println("获取html失败");
						Message msg = new Message();
						msg.what = GET_HTML_ERROR; //指定消息的类型 一般用一个int类型的数据 区分不同的消息
						handler.sendMessage(msg);
					}

				} catch (Exception e) {
					e.printStackTrace();
					//Toast.makeText(MainActivity.this, "获取html失败", 0).show();
					System.out.println("获取html失败");
					Message msg = new Message();
					msg.what = GET_HTML_ERROR; //指定消息的类型 一般用一个int类型的数据 区分不同的消息
					handler.sendMessage(msg);
				}

			};
		}.start();
	}
}

StreamTools.java 工具类, 将InputStream转换为String

public class StreamTools {
	/**
	 * 工具方法 把流里面的内容 转化成 String 字符串
	 * @param is 输入流
	 * @return String 字符串
	 * @throws IOException 
	 */
	public static String readFromStream(InputStream is) throws Exception{
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while((len = is.read(buffer))!=-1){
			baos.write(buffer, 0, len);
		}
		is.close();
		String result = baos.toString();
		if(result.contains("gb2312")){
			// result.getbytes("utf-8")
			byte[] temp = baos.toByteArray();
			result = new String(temp, "gb2312");
		}
		baos.close();
		return result;
	}
}



 

 

posted @ 2014-03-27 11:14  今晚打酱油_  阅读(233)  评论(0编辑  收藏  举报