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

2022-11-01,,,,

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;
}
}

Android -- 网络图片查看器,网络html查看器, 消息机制, 消息队列,线程间通讯的相关教程结束。

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

下载本文的Word格式文档,以方便收藏与打印。