高手指点,为何J2ME中通过HttpConnection读取HTML页面在真机上始终无法读取完整的HTML内容?高手指点,为何J2
高手指点,为何J2ME中通过HttpConnection读取HTML页面在真机上始终无法读取完整的HTML内容? 高手指点,为何J2ME中通过HttpConnection读取HTML页面在真机上始终无法读取完整的HTML内容? 我的代码片段如下: public class HtmlGetThread extends ThreadWrapper implements Runnable { private HttpConnection c = null; private String url = null; private Vector listeners = new Vector(); public static final int MAX_LENGTH = 1024; public HtmlGetThread(String url) { this.url = url; } public String getHtmlViaURL() { initConnection(); return getHtml(); } private void initConnection() { try { c = (HttpConnection) Connector.open(url); c.setRequestMethod(HttpConnection.GET); } catch (IOException e) { e.printStackTrace(); c = null; } } private String getHtml() { DataInputStream input = null; byte[] buffer; StringBuffer sb = new StringBuffer(); String ret = ""; try { int code = c.getResponseCode(); if (code != HttpConnection.HTTP_OK) { // listener.onError(code, hc.getResponseMessage()); return ""; } input = c.openDataInputStream(); int index = 0; // buffer index int reads; // each byte while (true) { buffer = new byte[MAX_LENGTH]; reads = input.read(buffer, 0, MAX_LENGTH); if (reads <= 0) break; index += reads; notifyBytesReceived(index); String s = new String(buffer, "gb2312"); sb.append(s); } /* * if (input.available() > 0) // 缓冲区已满,无法继续读取 return ""; */ } catch (IOException ioe) { ioe.printStackTrace(); } finally { if (input != null) try { input.close(); } catch (IOException ioe) { ioe.printStackTrace(); } } return ret; } public void run() { String html = getHtmlViaURL(); HtmlGetEvent e = new HtmlGetEvent(HtmlGetEvent.STATUS_OK, html); notifyHtmlGet(e); } public void addHtmlGetListener(IHtmlGetListener l) { listeners.addElement(l); } public void notifyHtmlGet(HtmlGetEvent e) { Enumeration enum = listeners.elements(); while (enum.hasMoreElements()) { Object o = enum.nextElement(); if (o instanceof IHtmlGetListener) { IHtmlGetListener l = (IHtmlGetListener) o; l.onHtmlGet(e); } } } public void notifyBytesReceived(int size) { Enumeration enum = listeners.elements(); while (enum.hasMoreElements()) { Object o = enum.nextElement(); if (o instanceof IHtmlGetListener) { IHtmlGetListener l = (IHtmlGetListener) o; l.onBytesReceived(size); } } } } 真机测试发现始终无法完整读取内容。------最佳解决方案--------------------
kjava在传输字符串的过程中,对字符串的长度是有限制的. 在nokia6300上面,一次性传输大概在300个字符左右.大于这个值后面的字符串读取不到了.建议你对字符串进行分割,然后分段传输,在获取.[其他解释] 把<=0改为<0试试。
while (true) { buffer = new byte[MAX_LENGTH]; reads = input.read(buffer, 0, MAX_LENGTH); if (reads < 0) break; index += reads; notifyBytesReceived(index); String s = new String(buffer, "gb2312"); sb.append(s); } [其他解释] public static final int MAX_LENGTH = 1024;
while (true) {
buffer = new byte[MAX_LENGTH];
reads = input.read(buffer, 0, MAX_LENGTH);
if (reads <= 0)
break;
这个值是不是有点小?设置大些4096 试试
[其他解释] 我测试了。还是不行。
IHtmlGetListener的定义如下:
public interface IHtmlGetListener {
public void onHtmlGet(HtmlGetEvent e);
public void onBytesReceived(int size);
}
有兴趣的高手可以实现一个MIDlet测试下这个HtmlGetThread类,
ThreadWrapper定义如下:
public class ThreadWrapper {
public void launchTread() {
if (this instanceof Runnable) {
Runnable r = (Runnable) this;
Thread t = new Thread(r);
t.start();
}
}
}
测试结果是public void onBytesReceived(int size);这里在通知监听者,监听者会在接收到一定数量的数据后就接收不到数据了,现象上就好像是数据一直都读不完,线程一直没有完成工作。
[其他解释] 引用: public static final int MAX_LENGTH = 1024; while (true) { buffer = new byte[MAX_LENGTH]; reads = input.read(buffer, 0, MAX_LENGTH); if (reads <= 0) break; 这个值是不是有点小?设置大些4096 试试 应该不是这个问题,这个值我反复设置过测试过,问题依然存在。
[其他解释] input = c.openDataInputStream(); int index = 0; // buffer index int reads; // each byte while (true) { buffer = new byte[MAX_LENGTH]; reads = input.read(buffer, 0, MAX_LENGTH); if (reads <= 0) break; 你把reads 返回的字节
再控制台一字符串的形式输出一下看下完整不?
InputStream in=c.openInputStream();
DataInputStream dis=new DataInputStream(in);
byte buf[]=new byte[in.available()];
in.read(buf);
result=new String(buf,"utf-8");
System.out.println(result);
[其他解释] while (true) {
buffer = new byte[MAX_LENGTH];
reads = input.read(buffer, 0, MAX_LENGTH);
if (reads <= 0)
break;
index += reads;
notifyBytesReceived(index);
String s = new String(buffer, "gb2312");
sb.append(s);
} 改成这样试试: ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] b1 = new byte[MAX_LENGTH]; int i; while ((i = is.read(b1)) != -1) { baos.write(b1, 0, i); index += reads; notifyBytesReceived(index); } b = baos.toByteArray(); String s = new String(b, "gb2312"); sb.append(s); baos.close(); baos = null;[其他解释]
引用: Java codeinput= c.openDataInputStream();int index=0;// buffer indexint reads;// each bytewhile (true) { buffer=newbyte[MAX_LENGTH]; reads= input.read(buffer,0, MAX_LENGTH);if (reads<=0)break; 你把reads 返回的字节 再控制台一字符串的形式输出一下看下完整不? InputStream in=c.openInputStream(); DataInputStream dis=new DataInputStream(in); byte buf[]=new byte[in.available()]; in.read(buf); result=new String(buf,"utf-8"); System.out.println(result); 在模拟器上是可以正常工作的,能够把数据完整读回。在手机上测试就不行
[其他解释] 引用: while (true) { buffer = new byte[MAX_LENGTH]; reads = input.read(buffer, 0, MAX_LENGTH); if (reads <= 0) break; index += reads; notifyBytesReceived(index); String s = new String(buffer, "gb2312"); sb.append(s); } 改成这样试试: ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] b1 = new byte[MAX_LENGTH]; int i; while ((i = is.read(b1)) != -1) { baos.write(b1, 0, i); index += reads; notifyBytesReceived(index); } b = baos.toByteArray(); String s = new String(b, "gb2312"); sb.append(s); baos.close(); baos = null; 这个代码写法我测试过了。还是不行
[其他解释] 这样应该是可以的 我这样读取图片都能读取出来的啊 public Image loadImage(String url) throws IOException {
HttpConnection hpc = null;
DataInputStream dis = null;
try {
mainForm.append(" " +
" " +
" " +
" "+ " 图片读取中请稍候..."); hpc = (HttpConnection) Connector.open(url); hpc.setRequestProperty("X-Online-Host", "s602.cn:8118"); int code = hpc.getResponseCode(); if (code == 200) { String contentType = hpc.getHeaderField("Content-Type"); if (contentType.indexOf("wml") != -1) { return loadImage(url); } } dis = new DataInputStream(hpc.openInputStream()); ByteArrayOutputStream dos = null; byte[] downim; int ch = (int) hpc.getLength(); if (ch != -1) { downim = new byte[ch]; dis.readFully(downim); } else { dos = new ByteArrayOutputStream(); int hh; while ((hh = dis.read()) != -1) { dos.write(hh); } downim = dos.toByteArray(); } return Image.createImage(downim, 0, downim.length); } catch (IOException e) { e.printStackTrace(); }catch (SecurityException s){ s.printStackTrace(); }finally { if (hpc != null) hpc.close(); if (dis != null) dis.close(); } return null; }[其他解释]
引用: 这样应该是可以的 我这样读取图片都能读取出来的啊? public Image loadImage(String url) throws IOException { HttpConnection hpc = null; DataInputStream dis = null; try { mainForm.append("? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? " + "? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? " + "? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? " + "? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "+ "? ? ? ? 图片读取中请稍候..."); hpc = (HttpConnection) Connector.open(url); hpc.setRequestProperty("X-Online-Host", "s602.cn:8118"); int code = hpc.getResponseCode(); if (code == 200) { String contentType = hpc.getHeaderField("Content-Type"); if (contentType.indexOf("wml") != -1) { return loadImage(url); } } dis = new DataInputStream(hpc.openInputStream()); ByteArrayOutputStream dos = null; byte[] downim; int ch = (int) hpc.getLength(); if (ch != -1) { downim = new byte[ch]; dis.readFully(downim); } else { dos = new ByteArrayOutputStream(); int hh; while ((hh = dis.read()) != -1) { dos.write(hh); } downim = dos.toByteArray(); } return Image.createImage(downim, 0, downim.length); } catch (IOException e) { e.printStackTrace(); }catch (SecurityException s){ s.printStackTrace(); }finally { if (hpc != null) hpc.close(); if (dis != null) dis.close(); } return null; }
你打开的图片有多大?
[其他解释] 都是几十k的吧
[其他解释] 我看了下至少在15k以上
[其他解释] 我测试过,我的程序有时读到9k的时候就不动了,有时读到34k的时候不动了。手机上又很难调试。。。。
[其他解释] 引用: kjava在传输字符串的过程中,对字符串的长度是有限制的. 在nokia6300上面,一次性传输大概在300个字符左右.大于这个值后面的字符串读取不到了.建议你对字符串进行分割,然后分段传输,在获取. 能不能请你详细介绍下这个限制?我也很怀疑是某些限制导致的问题。你说的这个传输字符串是怎么一回事?是在InputStream上read的长度有限制?还是说StringBuffer上append字符有限制?谢谢
[其他解释] 限制是在手机上面.
分割字符串传输,就是在服务器端.
手机客户服端,接收完字符串后,在拼接.
[其他解释] http://blog.csdn.net/kf156/archive/2009/11/02/4757919.aspx
用这例子测下看行不行。
[其他解释] 引用: 限制是在手机上面. 分割字符串传输,就是在服务器端. 手机客户服端,接收完字符串后,在拼接. 服务器端是不是就是所谓的chunked。手机客户端需要怎么做?
[其他解释] while (true) {
buffer = new byte[1024];
Log.error("To read");
reads = input.read(buffer, 0, 1024);
Log.error("Read");
if (reads < 0)
break;
index += reads;
notifyBytesReceived(index);
Log.error(String.valueOf(index) + "bytes received");
/*String s = new String(buffer);
sb.append(s);*/
buffer = null;
}
通过添加日志调试发现卡住的时候日志里只打了To read。后面那句Read的日志就没有了。
应该是堵塞在input.read上了。
这是为什么呢?
[其他解释] 个人感觉还是在读数据的地方出问题了,你可以试试catch的地方换成Throwable试试,我觉得在new String的时候会报一个编码异常。。
[其他解释] 引用: 再重新new 个线程试试…… 怎么new 线程?不是太懂你的意思。谢谢
我目前这段创建链接读取html就是在线程里完成的。跟UI是分开的。
[其他解释] 再重新new 个线程试试……[其他解释] 亚日升分真快 http://blog.csdn.net/kf156/archive/2009/11/02/4757919.aspx [其他解释] try{ reads = input.read(buffer, 0, 1024); }catch(){ //输出日志 } 看看是不是有什么异常了。[其他解释]
引用: 亚日升分真快 都是J2ME版得来的辛苦分
引用: 没有异常,while循环是包在try{}catch(Exception e){}里的。应该只要有异常就捕获了。 一进while就卡在这了?那是否有把这异常输出日志呢?
[其他解释] 引用: try{ reads = input.read(buffer, 0, 1024); }catch(){ //输出日志 } 看看是不是有什么异常了。 没有异常,while循环是包在try{}catch(Exception e){}里的。应该只要有异常就捕获了。
[其他解释] String s = new String(buffer, "gb2312");
sb.append(s);
这个地方有问题,你是截断流来创建字符串的,但是你不能保证你截断的地方正好是一个字符编码的末尾,有可能你截了一半,然后想创建字符串,就会失败抛出异常了,也许就导致了以无法读取完整的编码。按基本的网络连接获取数据的代码来看没什么问题。
[其他解释] 引用: 引用: 亚日升分真快 都是J2ME版得来的辛苦分 引用: 没有异常,while循环是包在try{}catch(Exception e){}里的。应该只要有异常就捕获了。 一进while就卡在这了?那是否有把这异常输出日志呢? 不是。notifyBytesReceived(index); 这句会通知监听者进度。
目前的测试看会读到165k的时候卡住。换个http地址读取的话又会在15k的时候卡住。看起来似乎没有什么规律。但不是进去就卡住
[其他解释] 就那么10几k的字符串,不用拆分吧?难道还是低端手机?
[其他解释] 又看了一下,你这个地方没有捕获异常,捕获的只是io异常,创建字符串的异常捕获不到,所以可能断了也不会通知你的。
[其他解释] 关注
[其他解释] 将
buffer = new byte[1024];
这句放到while的外面去看看
[其他解释] 想问一下怎么解决的