最佳的线程联网类

以前自己打开Http连接,从未开启过线程,我自己对线程用的也不是很熟悉,今天去论坛求救,立马得到结果,结果来自亚日的一篇文章J2ME http连接的例子,他的代码写的很清晰,代码结构也不错,是用lcdui的高级UI写的。

但我用的是LWUIT的包,很多写法和lcdui不一样,我就对着它的代码研究了一下,自己写了一个LWUIT的版本,非常感谢亚日提供的这个例子

首先看看亚日的例子,代码注释写的很清楚,看懂还是比较容易的。

代码
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.TextField;
import javax.microedition.midlet.MIDlet;
/**
* HttpDemo 增加网址输入以及取消功能
*
*
@author kf156(亚日)
*
*/
public class HttpTest extends MIDlet implements CommandListener {
public static final byte WAIT = 0;// 等待
public static final byte CONNECT = 1;// 连接中
public static final byte SUCCESS = 2;// 成功
public static final byte FAIL = 3;// 失败
int state;// 当前状态
Display display = Display.getDisplay(this);
Form form
= new Form("HttpTest");
// StringBuffer sb = new StringBuffer("");
// StringItem si = new StringItem(null, sb.toString());
Command connect = new Command("联网", Command.OK, 1);
Command cls
= new Command("清除网址", Command.OK, 1);
Command cancel
= new Command("取消", Command.CANCEL, 1);
Command exit
= new Command("退出", Command.EXIT, 1);
Command back
= new Command("返回", Command.BACK, 1);
ChoiceGroup cmwapCG;
// 接入方式
TextField urlTF;// 网址输入框
String url;// 网址
Http http;// 网络线程
Form page;// 页面
Alert waitPage;// 等待界面
public HttpTest() {
state
= WAIT;// 等待状态
// 初始化等待界面
waitPage = new Alert("请等待", "网络连接中...", null, AlertType.INFO);
waitPage.addCommand(cancel);
waitPage.setCommandListener(
this);
waitPage.setTimeout(Alert.FOREVER);
// 初始化页面
page = new Form("访问的页面");
page.addCommand(back);
page.setCommandListener(
this);
// 初始化
cmwapCG = new ChoiceGroup("网络接入方式:", Choice.MULTIPLE,
new String[] { "CMWAP" }, null);
urlTF
= new TextField("请输入网址:",
"http://avatar.csdn.net/5/F/0/2_kf156.jpg", 100, TextField.URL);
form.append(cmwapCG);
form.append(urlTF);
// form.append(si);
form.addCommand(connect);
form.addCommand(cls);
// form.addCommand(cancel);
form.addCommand(exit);
form.setCommandListener(
this);
}
protected void destroyApp(boolean b) {
}
protected void pauseApp() {
}
protected void startApp() {
display.setCurrent(form);
}
public void commandAction(Command c, Displayable d) {
if (c == connect) {// 联网
if (checkError())
return;
// display.setCurrent(waitPage);
http = new Http();
new Thread(http).start();
}
else if (c == cancel) {// 取消
http.cancel();
http
= null;
display.setCurrent(form);
}
else if (c == back) {// 返回
page.deleteAll();
display.setCurrent(form);
}
else if (c == cls) {// 清除数据
// cls();
urlTF.setString("");
}
else if (c == exit) {// 退出
destroyApp(true);
notifyDestroyed();
}
}
// private void cls() {
// form.deleteAll();// 删除日志
// sb.delete(0, sb.length());
// si.setText(null);
// form.append(cmwapCG);
// form.append(urlTF);
// form.append(si);
// }
/**
* 判断是否正确
*
*
@return
*/
private boolean checkError() {
url
= urlTF.getString();
if (state == CONNECT) {
addStr(
"当前已有网络连接,请稍候");
return true;
}
else if (url == null || url.trim().equals("")) {
addStr(
"url不能为空");
return true;
}
if (!url.toLowerCase().startsWith("http://")) {// 添加http://
url = "http://" + url;
}
System.out.println(url);
return false;
}
/**
* 添加文字
*
*
@param str
* 要添加的文字
*/
private void addStr(String str) {
// sb.append(str + "\n");
// si.setText(sb.toString());
System.out.println(str);
}
/**
* 获取URL域名
*
*
@param srcUrl
*
@param domain
* true为截域名,false为截地址
*
@return
*/
private String getURLhost(String srcUrl) {
int k = srcUrl.toLowerCase().indexOf("/", 7);
if (k == -1)
return srcUrl.substring(7);
return srcUrl.substring(7, k);
}
/**
*
* 字符串替换方法(字符串替换字符串)
*
*
@author kf156
*
*
@param text
* 文本
*
@param oldStr
* 旧字符串
*
@param newStr
* 新字符串
*
@return
*/
public static String replace(String text, String oldStr, String newStr) {
int oldLen = oldStr.length();
int k = 0;
while (k + oldLen <= text.length()) {// 检测到字符串末尾
k = text.indexOf(oldStr, k);// 从k处查找oldStr,并返回位置
if (k == -1)// 若查不到,则跳出
return text;
// 若有,则将其替换为newStr
text = text.substring(0, k) + newStr
+ text.substring(k += oldLen, text.length());
}
return text;
}
class Http implements Runnable {
HttpConnection http;
boolean cancel;// 是否取消
public void cancel() {
cancel
= true;
state
= WAIT;// 等待状态
}
public void run() {
// cls();
state = CONNECT;
addStr(
"网络连接中...");
InputStream is
= null;
try {
boolean cmwap = cmwapCG.isSelected(0);// 是否走CMWAP
String host = getURLhost(url);
System.out.println(host);
String _url
= cmwap ? replace(url, host, "10.0.0.172:80") : url;
http
= (HttpConnection) Connector.open(_url, Connector.READ,
true);
if (cmwap)
http.setRequestProperty(
"X-Online-Host", host);
http.setRequestMethod(HttpConnection.GET);
cmwapCG.setSelectedIndex(
0, true);
String contentType
= http.getHeaderField("Content-Type");
// System.out.println(contentType);
addStr("Content-Type=" + contentType);
if (cancel) {// 中途结束
addStr("已取消");
return;
}
if (contentType != null
&& contentType.indexOf("text/vnd.wap.wml") != -1) {// 过滤移动资费页面
addStr("移动资费页面,过滤!");
http.close();
http
= null;
http
= (HttpConnection) Connector.open(_url,
Connector.READ,
true);
if (cmwap)
http.setRequestProperty(
"X-Online-Host", host);
http.setRequestMethod(HttpConnection.GET);
contentType
= http.getHeaderField("Content-Type");
addStr(
"Content-Type=" + contentType);
}
int code = http.getResponseCode();
addStr(
"HTTP Code :" + code);
if (code == 200) {// 成功
addStr("网络联网成功,接收数据...");
is
= http.openInputStream();
byte[] b = new byte[1024];
int len = 0;
ByteArrayOutputStream baos
= new ByteArrayOutputStream();
DataOutputStream dos
= new DataOutputStream(baos);
while ((len = is.read(b)) != -1) {
if (cancel) {// 中途结束
addStr("已取消");
return;
}
dos.write(b,
0, len);
}
byte[] data = baos.toByteArray();
if (contentType != null
&& contentType.toLowerCase().indexOf("image") != -1) {// 图片
try {
Image image
= Image.createImage(data, 0,
data.length);
addStr(
"数据接收完毕,显示图片");
// form.append(image);
page.append(image);
}
catch (Exception e) {
addStr(
"生成图片失败 " + e.toString());
page.append(
"生成图片失败 " + e.toString());
}
}
else { // 文字
addStr("数据接收完毕,显示内容");
String s
= null;
if (contentType != null
&& contentType.toLowerCase().indexOf("utf-8") != -1)
s
= new String(data, "UTF-8");
else
s
= new String(data);
// form.append(s);
page.append(s);
}
data
= null;
dos.close();
dos
= null;
baos.close();
baos
= null;
is.close();
is
= null;
state
= SUCCESS;
}
else {
addStr(
"访问页面失败");
page.append(
"访问页面失败: " + code);
state
= FAIL;
}
}
catch (IOException e) {
addStr(
"联网发生异常:" + e.toString());
e.printStackTrace();
if (!cancel)
page.append(
"网络异常:" + e.toString());
state
= FAIL;
}
catch (Exception e) {
addStr(
"发生异常:" + e.toString());
e.printStackTrace();
if (!cancel)
page.append(
"异常:" + e.toString());
state
= FAIL;
}
finally {
if (is != null) {// 关闭is
try {
is.close();
}
catch (IOException e) {
e.printStackTrace();
}
is
= null;
}
if (http != null) {// 关闭http
try {
http.close();
}
catch (IOException e) {
e.printStackTrace();
}
http
= null;
}
}
if (!cancel)
display.setCurrent(page);
// 显示页面
}
}
}

 

 下面的代码是我用LWUIT改造的代码,代码可以自己修改一下,让代码结构更良好,可以把Http类抽出来。

 

代码
import com.sun.lwuit.CheckBox;
import com.sun.lwuit.Command;
import com.sun.lwuit.Display;
import com.sun.lwuit.Form;
import com.sun.lwuit.Image;
import com.sun.lwuit.Label;
import com.sun.lwuit.TextField;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.midlet.*;
/**
*
@author 水货程序员
* Demo作为学习交流使用
*/
public class HttpTest extends MIDlet implements ActionListener {
public static final byte WAIT = 0;//等待
public static final byte CONNECT = 1;//连接中
public static final byte SUCCESS = 2;//成功
public static final byte FAIL = 3;//失败
int state;
Command connect
= new Command("联网", 1);
Command cls
= new Command("清除网址", 2);
Command cancel
= new Command("取消", 3);
Command exit
= new Command("退出", 4);
Command back
= new Command("返回", 5);
CheckBox cmwapCG;
//接入方式
TextField urlTF;//网址输入框
String url;//网址
Http http;//网络线程
Form page;//页面
Form waitPage;//等待界面
public void actionPerformed(ActionEvent evt) {
int cmdId = evt.getCommand().getId();
switch (cmdId) {
case 1://连接
if (checkError()) {
return;
}
http
= new Http();
new Thread(http).start();
break;
case 2://清除网址
urlTF.setText("");
break;
case 3://取消
http.cancel();
http
= null;
showTestForm();
break;
case 4://退出
destroyApp(true);
notifyDestroyed();
break;
case 5://返回
showTestForm();
break;
}
}
/**
* 在LWUIT的主类里面,Form不能声明为属性,否则会出现NullPointerException。
* 取得图片后,再返回时,重新new一下cmwapCB,urlTF,否则会报
* Component is already contained in Container的异常。
*/
public void showTestForm() {
Form form
= new Form("HttpTest");
cmwapCG
= new CheckBox("CMWAP");
urlTF
= new TextField("http://avatar.csdn.net/5/F/0/2_kf156.jpg");
form.addComponent(cmwapCG);
form.addComponent(urlTF);
form.addCommand(connect);
form.addCommand(cls);
form.addCommand(exit);
form.addCommandListener(
this);
form.show();
}
public void startApp() {
Display.init(
this);
state
= WAIT;//等待
//waitPage = new Form()
page = new Form("访问的页面");
page.addCommand(back);
page.addCommandListener(
this);
cmwapCG
= new CheckBox("CMWAP");
urlTF
= new TextField("http://avatar.csdn.net/5/F/0/2_kf156.jpg");
url
= urlTF.getText();
showTestForm();
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
/**
* 检验URL正确性
*
@return
*/
private boolean checkError() {
url
= urlTF.getText();
if (state == CONNECT) {
System.out.println(
"当前已有网络连接,请稍后");
return true;
}
else if (url == null || url.trim().equals("")) {
return true;
}
if (!url.toLowerCase().startsWith("http://")) {
// 添加http://
url = "http://" + http;
}
System.out.println(url);
return false;
}
/**
* 获取URL域名
* 例如http://www.google.cn,域名为www.google.cn
*
http://blog.csdn.net/pjw100,域名为blog.csdn.net,会把/pjw100截掉。
*
@param srcUrl
*
@return
*/
private String getURLhost(String srcUrl) {
int k = srcUrl.toLowerCase().indexOf("/", 7);
if (k == -1) {
return srcUrl.substring(7);
}
return srcUrl.substring(7, k);
}
public static String replace(String text, String oldStr, String newStr) {
int oldLen = oldStr.length();
int k = 0;
while (k + oldLen < text.length()) {//检测到字符串末尾
k = text.indexOf(oldStr, k);//查找字符串
if (k == -1) {//若查不到,跳出
return text;
}
//有则替换
text = text.substring(0, k) + newStr + text.substring(k += oldLen, text.length());
}
return text;
}
class Http implements Runnable {
HttpConnection http;
boolean cancel;//是否取消
public void cancel() {
cancel
= true;
state
= WAIT;//等待状态
}
public void run() {
state
= CONNECT;
System.out.println(
"网络连接中...");
InputStream is
= null;
try {
boolean cmwap = cmwapCG.isSelected();
String host
= getURLhost(url);
System.out.println(host);
String _url
= cmwap ? replace(url, host, "10.0.0.172:80") : url;
http
= (HttpConnection) Connector.open(_url, Connector.READ, true);
if (cmwap) {
http.setRequestProperty(
"X-Online-Host", host);
}
http.setRequestMethod(HttpConnection.GET);
String contentType
= http.getHeaderField("Content-Type");
if (cancel) {//中途取消
return;
}
if (contentType != null && contentType.indexOf("text/vnd.wap.wml") != -1) {
//过滤移动资费
http.close();
http
= null;
http
= (HttpConnection) Connector.open(_url, Connector.READ, true);
if (cmwap) {
http.setRequestProperty(
"X-Online-Host", host);
}
http.setRequestMethod(HttpConnection.GET);
contentType
= http.getHeaderField("Content-Type");
}
int code = http.getResponseCode();
if (code == 200) {//联网成功
is = http.openInputStream();
byte[] b = new byte[1024];
int len = 0;
ByteArrayOutputStream baos
= new ByteArrayOutputStream();
DataOutputStream dos
= new DataOutputStream(baos);
while ((len = is.read(b)) != -1) {
if (cancel) {
//取消
return;
}
dos.write(b,
0, len);
}
byte[] data = baos.toByteArray();
if (contentType != null && contentType.toLowerCase().indexOf("image") != -1) {
try {
Image image
= Image.createImage(data, 0, data.length);
System.out.println(
"数据接收完毕,显示图片");
Label l
= new Label(image);
page.addComponent(l);
}
catch (Exception ex) {
System.out.println(
"生成图片失败" + ex.toString());
Label err
= new Label("生成图片失败" + ex.toString());
page.addComponent(err);
}
}
else {//文字
System.out.println("数据接收完毕,显示内容");
String s
= null;
if (contentType != null && contentType.toLowerCase().indexOf("utf-8") != -1) {
s
= new String(data, "UTF-8");
}
else {
s
= new String(data);
}
page.addComponent(
new Label(s));
}
data
= null;
dos.close();
dos
= null;
baos.close();
baos
= null;
is.close();
is
= null;
state
= SUCCESS;
}
else {
page.addComponent(
new Label("访问页面失败:" + code));
state
= FAIL;
}
}
catch (IOException ex) {
System.out.println(
"联网发生异常:" + ex.toString());
ex.printStackTrace();
if (!cancel) {
page.addComponent(
new Label("网络异常:" + ex.toString()));
}
state
= FAIL;
}
catch (Exception ex) {
System.out.println(
"发生异常" + ex.toString());
ex.printStackTrace();
if (!cancel) {
page.addComponent(
new Label("异常:" + ex.toString()));
}
state
= FAIL;
}
finally {
if (is != null) {//关闭is
try {
is.close();
}
catch (IOException ex) {
ex.printStackTrace();
}
is
= null;
}
if (http != null) {//关闭http
try {
http.close();
}
catch (IOException ex) {
ex.printStackTrace();
}
http
= null;
}
}
if (!cancel) {
page.show();
}
}
}
}

 

 

 

 

posted @ 2009-12-08 00:45  Sunny Peng  阅读(2054)  评论(0编辑  收藏  举报