以前自己打开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(); } } }}