﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-土豆娃娃的家园-文章分类-J2ME</title><link>http://www.blogjava.net/it206/category/17358.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 27 Mar 2007 10:38:21 GMT</lastBuildDate><pubDate>Tue, 27 Mar 2007 10:38:21 GMT</pubDate><ttl>60</ttl><item><title>1.0 实现图片的翻转</title><link>http://www.blogjava.net/it206/articles/84396.html</link><dc:creator>土豆娃娃</dc:creator><author>土豆娃娃</author><pubDate>Wed, 29 Nov 2006 09:47:00 GMT</pubDate><guid>http://www.blogjava.net/it206/articles/84396.html</guid><wfw:comment>http://www.blogjava.net/it206/comments/84396.html</wfw:comment><comments>http://www.blogjava.net/it206/articles/84396.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/it206/comments/commentRss/84396.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/it206/services/trackbacks/84396.html</trackback:ping><description><![CDATA[Image img1;//原始的不翻转的图片 <br />age img2;//要翻转成的图片 <br />g1 = createImage("/img.png"); <br />g2 = createTransferImage(img1, TRANS_NONE); <br />drawImage(img2,0,0,20); <br /> <br />/////////////////////////////////////////////////////////////// <br /> <br />public final static int TRANS_NONE = 0;//不翻 <br /> <br />public final static int TRANS_MIRROR = 1;//左右镜像 <br /> <br />public final static int TRANS_MIRROR_ROT180 = 2;//上下镜像变换 <br /> <br />public final static int TRANS_ROT90 = 3;//顺时针旋转90度 <br /> <br />public final static int TRANS_ROT180 = 4;//(暂时有问题) <br /> <br />public final static int TRANS_ROT270 = 5;//顺时针旋转270度 <br /> <br />public final static int TRANS_MIRROR_ROT90 = 6;//先左右镜像变换，再顺时针旋转90度 <br /> <br />public final static int TRANS_MIRROR_ROT270 = 7;//先左右镜像变换，再顺时针旋转270度 <br /> <br /> <br /> <br />private   Image createTransferImage(Image image, int trans) { <br /> <br />          int w = image.getWidth(); <br />        int h = image.getHeight(); <br />        int ARGBData[] = new int[w * h];//原始图片 <br />        int tranARGBData[] = new int[w * h];//翻转后的图片存放的图片 <br />        image.getRGB(ARGBData, 0, w, 0, 0, w, h); <br />        Image retImage=null; <br /> <br />          switch(trans) <br />        { <br />          case TRANS_NONE://无翻转 <br />            retImage=image; <br />            break; <br /> <br />            case TRANS_MIRROR://左右水平镜像 <br />            retImage=Image.createRGBImage(getMirror(ARGBData, w, h), w, h, true); <br />            break; <br /> <br />            case TRANS_MIRROR_ROT180://上下垂直镜像 <br />          for (int y = 0, y1 = h; y &lt; h; y++, y1--) { <br />            for (int x = 0, x1 = w; x &lt; w; x++, x1--) { <br />                tranARGBData[y * w + x] = ARGBData[y1 * w - (w - x1 + 1)]; <br />            } <br />          } <br />          retImage=Image.createRGBImage(getMirror(tranARGBData, w, h), w, h, true); <br />          break; <br /> <br />            case TRANS_ROT90: //顺时针90度/逆时针270度 <br />            w = image.getHeight(); <br />            h = image.getWidth(); <br />            for (int y = 0; y &lt; h; y++) { <br />              for (int x = 0; x &lt; w; x++) { <br />                tranARGBData[y * w + x] = ARGBData[x * h + y]; <br />              } <br />            } <br />            retImage=Image.createRGBImage(getMirror(tranARGBData, w, h), w, h, true); <br />            break; <br /> <br />            case TRANS_ROT180://顺/逆时针180度 <br />          w = image.getHeight(); <br />          h = image.getWidth(); <br />          for (int y = 0, y1 = h; y &lt; h; y++, y1--) { <br />            for (int x = 0, x1 = w; x &lt; w; x++, x1--) { <br />                tranARGBData[y * w + x] = ARGBData[y1 * w - (w - x1 + 1)]; <br />            } <br />          } <br />          retImage= Image.createRGBImage(tranARGBData, w, h, true); <br />          break; <br /> <br />            case TRANS_MIRROR_ROT270://顺时针270度/逆时针90度 <br />          w = image.getHeight(); <br />          h = image.getWidth(); <br />          for (int y = 0, y1 = h; y &lt; h; y++, y1--) { <br />            for (int x = 0, x1 = w; x &lt; w; x++, x1--) { <br />                tranARGBData[y * w + x] = ARGBData[x1 * h - (h - y1 + 1)]; <br />            } <br />          } <br />          retImage= Image.createRGBImage(getMirror(tranARGBData, w, h), w, h, true); <br />          break; <br /> <br />            case TRANS_MIRROR_ROT90://先镜像再顺时针翻转90度 <br />            w = image.getHeight(); <br />            h = image.getWidth(); <br />            for (int y = 0, y1 = h; y &lt; h; y++, y1--) { <br />              for (int x = 0, x1 = w; x &lt; w; x++, x1--) { <br />                tranARGBData[y * w + x] = ARGBData[x1 * h - (h - y1 + 1)]; <br />              } <br />            } <br />            retImage=Image.createRGBImage(tranARGBData, w, h, true); <br />            break; <br /> <br /> <br /> <br />            case -270://先镜像再顺时针翻转270度 <br />            w = image.getHeight(); <br />            h = image.getWidth(); <br />            for (int y = 0; y &lt; h; y++) { <br />              for (int x = 0; x &lt; w; x++) { <br />                tranARGBData[y * w + x] = ARGBData[x * h + y]; <br />              } <br />            } <br />            retImage=Image.createRGBImage(tranARGBData, w, h, true); <br />            break; <br /> <br />              default: <br />              break; <br />        } <br />        return retImage; <br />      } <br />      int[] getMirror(int[] ARGBData, int w, int h) {//左右水平镜像 <br />        int tranARGBData[] = new int[w * h]; <br />        for (int y = 0; y &lt; h; y++) { <br />          for (int x = 0; x &lt; w; x++) { <br />              tranARGBData[y * w + x] = ARGBData[y * w + (w - x - 1)]; <br />          } <br />        } <br />        return tranARGBData;<br />}<img src ="http://www.blogjava.net/it206/aggbug/84396.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/it206/" target="_blank">土豆娃娃</a> 2006-11-29 17:47 <a href="http://www.blogjava.net/it206/articles/84396.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MIDP 1.0 HttpConnection类的robust封装</title><link>http://www.blogjava.net/it206/articles/81654.html</link><dc:creator>土豆娃娃</dc:creator><author>土豆娃娃</author><pubDate>Fri, 17 Nov 2006 00:52:00 GMT</pubDate><guid>http://www.blogjava.net/it206/articles/81654.html</guid><wfw:comment>http://www.blogjava.net/it206/comments/81654.html</wfw:comment><comments>http://www.blogjava.net/it206/articles/81654.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/it206/comments/commentRss/81654.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/it206/services/trackbacks/81654.html</trackback:ping><description><![CDATA[一、“NetConnection”简介：

<br />转述Matrix上 zhengyun_ustc所述：“你的HttpConnection是否封装的足够健壮呢？遇到各种情况，你是否有信心应对呢？譬如说，你要请求的 Response包实在太大，以至于运营商给你掐了告诉你说超时；譬如说你是不是总要自己写一个线程来专门作http连接？譬如说有一些移动运营商设置了 caching proxy servers，妨碍了你的测试。”

为了解决这个问题，一位日本程序员“JAY-F”针对MIDP1.0提供了一种robust的“NetConnection”封装。这个HttpConnnection类负责管理连接并易于使用。

<br />二、“NetConnection”特性：

1. 跨过Proxy-server阻碍：

一些移动网络放置了代理服务器用来提高访问速度，但是它的cache也成为了开发人员测试/调试程序的一大障碍。“NetConnection”类使用一个简单的http request属性将server上的代理功能关闭掉。

2. 使用线程分离的连接模式：

本类可以使用单线程、多线程两种模式运行，只要设置一个简单的标志即可。

3. 支持Http request range：

由于服务商在其网络上可能存在一些针对回应数据最大长度的限制，所以“NetConnection”类提供了构造request URL的功能使回应数据分为多个数据包。从而去除了前面的限制。

<br />三、netConnection是如何实现的？

1。netConnection类结构分析：

此类实现了Runnable接口，其运行模式支持多线程模式：当前只能由一个线程使用资源，其它线程wait。

<br />此类使用了一些静态成员变量：


        <br /><br />    //当前只能由一个线程使用singleton。
        <br />        private static NetConnection singleton = new NetConnection();

        <br /><br />        private static HttpConnection httpConn;

        <br /><br />        private static String url;

        <br /><br />        private static String method;

        <br /><br />        private static byte[] data;
                

        <br /><br />        private static String contentType;
        

        <br /><br />        private static long lowRange;
        

        <br /><br />        private static long highRange;
        

        <br /><br />        private static boolean disableProxy;
        

        <br /><br />        private static boolean detached;
        
        <br /><br />        private static byte[] response;



<br />类方法：


<br /><br />//线程run方法
<br />public void run()

<br /><br />//当前运行的线程执行完毕后，通报给其它的由于等待资源而wait状态的线程
<br />private synchronized void forceNotify() 

/<br /><br />/当资源正在被其它线程使用时，当前线程进入wait状态
<br />private synchronized void forceWait()

<br /><br />//关闭http连接
<br />private static void severConnection()



<br /><br /><br />由于使用了这些static成员变量，所以一些操作方法需要同步（synchronized）。

<br /><br /><br />2。netConnection核心代码解析：

<br /><br />netConnection类的实现思想很简单，就是设置一些request属性和对于GET方法构造一个特殊的URL。更重要的是其作者对http协议的深入理解、严谨的代码风格值得吾辈学习、研究。这也是本人分析其核心代码的一大原因。


<br /><br /><br /><br />/**
 <br /> * 实现了连接逻辑。
 <br /> * 调用者可以在分离的线程中使用netConnection类的静态连接。 <br /> * @throws IllegalStateException 如果此方法直接其它类调用则抛出该异常
 <br /> */
<br />public void run() {
        
        <br />    if (url == null) {
                <br />        throw new IllegalStateException("Cannot invoke this method!");
        <br />    }

        
        <br /><br />    DataOutputStream dos = null;
        <br />    DataInputStream dis = null;
        <br />    StringBuffer buffer = null;

        <br /><br />    try {

                <br /><br />        int permissions = 0;
                
                <br /><br />        //根据method值，设置Connector的权限（READ/READ_WRITE）
                <br />        if (HttpConnection.GET.equals(method)) {
                        <br />            permissions = Connector.READ;
                <br />        } else if (HttpConnection.POST.equals(method)) {
                        <br />            permissions = Connector.READ_WRITE;
                <br />        }
                
                <br /><br />        //如果关闭server代理功能，则构造noProxyUrl。
                <br />        <br />        //原理：使用timestamp作为该URL中no-proxy参数值，
                <br />        <br />        //        致使server视其为client发来的新请求。
                <br /><br />        if (disableProxy) {
                        
                        <br />            boolean hasQueryParams = false;
                        
                        char[] ca = url.toCharArray();
                        <br />            //判断原URL中是否含有参数
                        <br />            for (int loop = 0; loop &lt; url.length(); loop++) {
                                
                                <br />                if (ca[loop] == '?') {
                                        hasQueryParams = true;
                                        break;
                                <br />            }
                        <br />        }
                        
                        <br />        //由于需要多次字符串拼接，所以使用可提供效率的StringBuffer类
                        <br />        StringBuffer noProxyUrl = new StringBuffer();

                        <br />        //将原URL内容复制到noProxyUrl
                        noProxyUrl.append(url);

                        <br />        //如果原URL中含有参数，
                        <br />        //  则需要在noProxyUrl中增加"&amp;"，
                        <br />        //  否则直接在noProxyUrl中增加"?"，
                        <br />        //  这样做为了后面增加no-proxy参数做准备。
                        <br />        if (hasQueryParams) {
                                <br />            noProxyUrl.append("&amp;");
                        <br />        } else {
                                <br />            noProxyUrl.append("?");
                        <br />        }

                        <br />        //增加no-proxy参数
                        noProxyUrl.append("no-proxy=");
                                     noProxyUrl.append(System.currentTimeMillis()); <br />        // timestamp
                        
                        <br />        //将构造好的noProxyUrl复制到原URL
                        <br />        url = noProxyUrl.toString();
                }
                
                

                <br />        // 打开Http 连接
                httpConn = (HttpConnection) Connector.open(url, permissions, true);
                <br />        //设置request方法
                httpConn.setRequestMethod(method);

                <br />        //如果request权限为READ（即request方法为GET），
                <br />        //则需要设置http request属性的Range。
                <br />        //原理：设置http request属性的Range后的，
                <br />        //        server接收到该request后将把response数据分成小部分发回。
                <br />        //        从而避免了部分运营商对http response size的限制。
                <br />        if (permissions == Connector.READ) {        
                        <br />            if (lowRange &gt; -1 &amp;&amp; lowRange &lt; highRange) {<br />                 StringBuffer range = new StringBuffer();
                                
                                range.append("bytes=");
                                                        range.append(lowRange);
                                <br />                 range.append("-");<br />                 range.append(highRange);
                                
                                    <br />                  httpConn.setRequestProperty("Range", range.toString());
                        <br />        }
                <br />        //否则，request权限为READ_WRITE（即request方法为POST），
                <br />        //那么设置request的Content-Type属性。
                <br />        } else if (permissions == Connector.READ_WRITE) {
                        <br />        // POST request
                        httpConn.setRequestProperty("Content-Type", contentType);
                        dos = httpConn.openDataOutputStream();
                        dos.write(data);
                <br />}
        
        } catch (Exception e) {
        
                exceptionPipe = e;
                //如果程序运行在多线程模式，则在异常发生后需要唤醒其它睡眠的线程继续run
                if (detached) {
                        forceNotify();
                }
                
                return;
                
        } finally {

                try {
                        try {
                                if (dos != null) {
                                        // 关闭dos
                                        dos.close();
                                }
                        } catch (Exception e) {
                                // 如果程序运行在多线程模式，则在异常发生后需要唤醒其它睡眠的线程继续run
                                if (exceptionPipe == null) {
                                        exceptionPipe = e;
                                        
                                        if (detached) {
                                                forceNotify();
                                        }
                                        return;
                                }
                        } finally {
                                dos = null;
                        }
                        
                        // 读取http连接的回应代码
                        int responseCode = httpConn.getResponseCode();
                        
                        //当request方法为GET，并设置了request range时，接收到的回应代码为HTTP_PARTIAL
                        //当request方法为POST，接收到的回应代码为HTTP_OK
                        //如果上述两种回应代码均没有收到，则表明连接失败或者出问题
                        if (responseCode != HttpConnection.HTTP_OK
                                        &amp;&amp; responseCode != HttpConnection.HTTP_PARTIAL) {

                                if (exceptionPipe == null) {
                                        StringBuffer errorCode = new StringBuffer();
                                        errorCode.append("Response code from server: ");
                                        errorCode.append(responseCode);
                                        errorCode.append("\nMessage: [");
                                        errorCode.append(httpConn.getResponseMessage());
                                        errorCode.append("]");
                                        
                                        exceptionPipe = new IOException(errorCode.toString());
                                        
                                        if (detached) {
                                                forceNotify();
                                        }
                                        return;
                                }
                        }

                        //如果收到了上述的两种回应代码之一，则可以继续读取server的response数据
                        dis = httpConn.openDataInputStream();

                        //循环读取repsonse数据
                        int ch;
                        buffer = new StringBuffer();
                while ((ch = dis.read()) != -1) {
                        buffer.append((char) ch);
                }

                //将response数据进行必要的编码转换                 
                        response = buffer.toString().getBytes("ISO8859_1");
                        //接收到回应后，表明整个http会话过程结束，线程将结束。
                        //如果程序运行在多线程模式，则此时需要唤醒其它睡眠的线程继续run
                        if (detached) {
                                forceNotify();
                        }
                        
                        return;

                } catch (Exception e) {
                        
                        if (exceptionPipe == null) {
                                exceptionPipe = e;
                                
                                if (detached) {
                                        forceNotify();
                                }
                                
                                return;
                        }
                } finally {
                    
                        try {
                                if (dis != null) {
                                        // 关闭dis
                                        dis.close();
                                }
                        } catch (Exception e) {
                                // 若关闭dis时发生异常，则进行异常处理
                                if (exceptionPipe == null) {
                                        exceptionPipe = e;
                                        
                                        if (detached) {
                                                forceNotify();
                                        }
                                        return;
                                }
                        } finally {
                                dis = null;
                        }
                        
                        try {
                                if (httpConn != null) {
                                        //关闭http连接
                                        httpConn.close();

                                        httpConn = null;
                                }
                        } catch (Exception e) {

                                if (exceptionPipe == null) {
                                        exceptionPipe = e;
                                        
                                        if (detached) {
                                                forceNotify();
                                        }
                                        return;
                                }
                        }
                }
        }
}



五、参考资料：

源代码下载
HTTP/1.1定义<img src ="http://www.blogjava.net/it206/aggbug/81654.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/it206/" target="_blank">土豆娃娃</a> 2006-11-17 08:52 <a href="http://www.blogjava.net/it206/articles/81654.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>