The NoteBook of EricKong

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

#

Eclipse 3.3版的需要用cdt4(cdt4.03)。下载后,安照说明安装:

To use this zip file, in the menu Help->SoftwareUpdates->Find and Install..., select Search for new features to install, click New Archived Site..., and point at the zip file. The Update Manager will start up and you can select the features you want to install. You will at nead require the C/C++ Development Tooling feature which is the CDT runtime.

更多版本的cdt下载:http://download.eclipse.org/tools/cdt/builds/
/Files/jjshcc/mingw-get-inst-20120426.rar

/Files/jjshcc/mingw-get-inst-20110530.rar

posted @ 2012-05-21 09:48 Eric_jiang 阅读(1378) | 评论 (3)编辑 收藏

 

有一个UTF-8编码的文本文件,用FileReader读取到一个字符串,然后转换字符集:str=new String(str.getBytes(),"UTF-8");结果大部分中文显示正常,但最后仍有部分汉字显示为问号!
Java代码 
public static List<String> getLines(String fileName){  
        List<String> lines=new ArrayList<String>();  
        try {  
            BufferedReader br = new BufferedReader(new FileReader(fileName));  
            String line = null;  
            while ((line = br.readLine()) != null) {  
                lines.add(new String(line.getBytes("GBK"),"UTF-8"));  
            }  
            br.close();  
        } catch (FileNotFoundException e) {  
        }catch (IOException e) {}  
        return lines;  
    } 

public static List<String> getLines(String fileName){
  List<String> lines=new ArrayList<String>();
  try {
   BufferedReader br = new BufferedReader(new FileReader(fileName));
   String line = null;
   while ((line = br.readLine()) != null) {
    lines.add(new String(line.getBytes("GBK"),"UTF-8"));
   }
   br.close();
  } catch (FileNotFoundException e) {
  }catch (IOException e) {}
  return lines;
 }

 

文件读入时是按OS的默认字符集即GBK解码的,我先用默认字符集GBK编码str.getBytes(“GBK”),此时应该还原为文件中的字节序列了,然后再按UTF-8解码,生成的字符串按理说应该就应该是正确的。

为什么结果中还是有部分乱码呢?
问题出在FileReader读取文件的过程中,FileReader继承了InputStreamReader,但并没有实现父类中带字符集参数的构造函数,所以FileReader只能按系统默认的字符集来解码,然后在UTF-8 -> GBK -> UTF-8的过程中编码出现损失,造成结果不能还原最初的字符。

原因明确了,这个问题解决起来并不困难,用InputStreamReader代替FileReader,InputStreamReader isr=new InputStreamReader(new FileInputStream(fileName),"UTF-8");这样读取文件就会直接用UTF-8解码,不用再做编码转换。
Java代码 
public static List<String> getLines(String fileName){  
        List<String> lines=new ArrayList<String>();  
        try {  
            BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(fileName),"UTF-8"));  
            String line = null;  
            while ((line = br.readLine()) != null) {  
                lines.add(line);  
            }  
            br.close();  
        } catch (FileNotFoundException e) {  
        }catch (IOException e) {}  
        return lines;  
    } 

 

posted @ 2012-04-28 21:00 Eric_jiang 阅读(5526) | 评论 (2)编辑 收藏

public static String decodeUnicode(String theString) {

        
char aChar;

        
int len = theString.length();

        StringBuffer outBuffer 
= new StringBuffer(len);

        
for (int x = 0; x < len;) {

            aChar 
= theString.charAt(x++);

            
if (aChar == '\\'{

                aChar 
= theString.charAt(x++);

                
if (aChar == 'u'{

                    
// Read the xxxx

                    
int value = 0;

                    
for (int i = 0; i < 4; i++{

                        aChar 
= theString.charAt(x++);

                        
switch (aChar) {

                        
case '0':

                        
case '1':

                        
case '2':

                        
case '3':

                        
case '4':

                        
case '5':

                        
case '6':
                        
case '7':
                        
case '8':
                        
case '9':
                            value 
= (value << 4+ aChar - '0';
                            
break;
                        
case 'a':
                        
case 'b':
                        
case 'c':
                        
case 'd':
                        
case 'e':
                        
case 'f':
                            value 
= (value << 4+ 10 + aChar - 'a';
                            
break;
                        
case 'A':
                        
case 'B':
                        
case 'C':
                        
case 'D':
                        
case 'E':
                        
case 'F':
                            value 
= (value << 4+ 10 + aChar - 'A';
                            
break;
                        
default:
                            
throw new IllegalArgumentException(
                                    
"Malformed   \\uxxxx   encoding.");
                        }


                    }

                    outBuffer.append((
char) value);
                }
 else {
                    
if (aChar == 't')
                        aChar 
= '\t';
                    
else if (aChar == 'r')
                        aChar 
= '\r';

                    
else if (aChar == 'n')

                        aChar 
= '\n';

                    
else if (aChar == 'f')

                        aChar 
= '\f';

                    outBuffer.append(aChar);

                }


            }
 else

                outBuffer.append(aChar);

        }


        
return outBuffer.toString();

    }

posted @ 2012-04-26 17:44 Eric_jiang 阅读(477) | 评论 (1)编辑 收藏

     摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->import java.io.BufferedReader; import java.io.InputStream; import java.io.Inp...  阅读全文
posted @ 2012-04-23 14:48 Eric_jiang 阅读(2234) | 评论 (2)编辑 收藏

Outgoing Tunnels :


Local port forwarding (an outgoing tunnel) forwards traffic coming to a local port to a specified remote port.

Example: On Unix, when you issue the command

$ ssh2 -L 1234:localhost:23 username@host

all traffic coming to port 1234 on the client (localhost) will be forwarded to port 23 on the server (host).

Note that the localhost definition will be resolved by the SSH Tectia Server after the connection is established. In this case localhost therefore refers to the server (host) itself.

Note: It is important to understand that if you have three hosts, client, sshdserver, and appserver, and you forward the traffic coming to the client's port x to the appserver's port y, only the connection between the client and sshdserver will be secured. See Figure Forwarding to a third host. The command you use would be similar to the following:

$ ssh2 -L x:appserver:y username@sshdserver


clientserver-tunnelarch2-5.gif
Figure : Forwarding to a third host

When using SSH Tectia Client on Windows, the tunneling settings can be made under Profile Settings -> Tunneling.


Incoming Tunnels :

Remote port forwarding (an incoming tunnel) does the opposite to local port forwarding: it forwards traffic coming to a remote port to a specified local port.

For example, if you issue the following command

$ ssh2 -R 1234:localhost:23 username@host

all traffic which comes to port 1234 on the server (host) will be forwarded to port 23 on the client (localhost).

When using SSH Tectia Client on Windows, the tunneling settings can be made under Profile Settings -> Tunneling.


posted @ 2012-04-23 12:21 Eric_jiang 阅读(324) | 评论 (0)编辑 收藏

屏幕大小

1、不同的layout

     Android手机屏幕大小不一,有480x320,640x360,800x480.怎样才能让App自动适应不同的屏幕呢? 其实很简单,只需要在res目录下创建不同的layout文件夹,比如:layout-640x360,layout-800x480,所有的layout文件在编译之后都会写入R.java里,而系统会根据屏幕的大小自己选择合适的layout进行使用。

2、hdpi、mdpi、ldpi

     前的版本中,只有一个drawable,而2.1版本中有drawable-mdpi、drawable-ldpi、drawable-hdpi三个,这三个主要是为了支持多分辨率。

drawable- hdpi、drawable- mdpi、drawable-ldpi的区别:

  1. drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854)
  2. drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x480)
  3. drawable-ldpi里面存放低分辨率的图片,如QVGA (240x320)

系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片。在开发程序时为了兼容不同平台不同屏幕,建议各自文件夹根据需求均存放不同版本图片。

屏幕方向

1、横屏竖屏自动切换

     可以在res目录下建立layout-port和layout-land两个目录,里面分别放置竖屏和横屏两种布局文件,这样在手机屏幕方向变化的时候系统会自动调用相应的布局文件,避免一种布局文件无法满足两种屏幕显示的问题。

2、禁用自动切换

只需要在AndroidManifest.xml文件中加入android:screenOrientation属性限制。

  • Android:screenOrientation="landscape" //是限制此页面横屏显示
  • Android:screenOrientation="portrait"     //是限制此页面数竖屏显示

字体自适应大小

方法1:

首先根据不同分辨率获取不同字体大小。
在RES里创建
values-480x320/strings.xml 里面设置<dimenname="Text_size">30px</dimen>

values-800x400/strings.xml 里面设置<dimenname="Text_size">30px</dimen>

分别代表480X320 和 800X400分辨率情况下 字号为30px和40px;

在java文件中这样调用

int sizeOfText = (int)this.getResources().getDimension(R.dimen.Text_size);

方法2:

在视图的 onsizechanged里获取视图宽度,一般情况下默认宽度是320,所以计算一个缩放比率rate = (float)w/320   w是实际宽度
然后在设置字体尺寸时 paint.setTextSize((int)(8*rate)); 
 8是在分辨率宽为320 下需要设置的字体大小实际字体大小 = 默认字体大小x  rate


posted @ 2012-04-20 15:12 Eric_jiang 阅读(2602) | 评论 (2)编辑 收藏

1. 设置android手机为USB调试模式。步骤:设置> 应用程序> 开发>选择USB调试;

2. 用USB连接手机和电脑,并确保成功。步骤: 在windows下执行c:adb devices, 查看手机是否已经连接成功;

 3. 设置应用程序为调试模式。操作: 编辑AndroidManifest.xml 增加调试参数android:debuggable="true", 如下:

<application android:icon="@drawable/icon"  android:label="@string/app_name" android:debuggable="true">

 4. 执行真机调试操作:ECLIPSE调试对话框中,Target窗口中选择Manual,点击debug按钮,选择真机设备,开始调试。

注:不管是否启用ECLIPSE环境,任何Android软件只要在真机上运行发生异常,都可以在命令行窗口下查看具体异常信息:

 执行:.adb logcat 可以查看到更多的系统异常消息。在这些消息中要注意查看Caused by:打 头的行,这些行指明了在哪行代码出的错误。

posted @ 2012-04-17 09:39 Eric_jiang 阅读(1023) | 评论 (1)编辑 收藏

描述:

如何检查后台服务(Android的Service类)是否正在运行?我希望我的Activity能够显示Service的状态,然后我可以打开或者关闭它。

 

回答:

Android系统提供了一个函数ActivityManager.getRunningServices可以列出当前正在运行的后台服务线程

private boolean isServiceRunning() {
    ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if ("com.example.MyService".equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

这个方法是可靠的,因为这是由Android系统提供的服务查询办法。
所以以来于OnDestroy或者OnXXX方法,甚或是Binders以及静态变量的方法都是不可靠的,因为作为一个开发者,你永远不知道Android系统什么时候会杀掉你的进程来释放内存,那些回调函数很可能根本没机会被调用。

另外,关于如果希望手工检查所有后台服务的运行状态,见如何观察和控制正在运行的Android后台服务.

posted @ 2012-04-11 17:33 Eric_jiang 阅读(9786) | 评论 (1)编辑 收藏

方法一:(java习惯,在android不推荐使用)

刚刚开始接触android线程编程的时候,习惯好像java一样,试图用下面的代码解决问题

new Thread( new Runnable() {
public void run() {
myView.invalidate();
}
}).start();

可以实现功能,刷新UI界面。但是这样是不行的,因为它违背了单线程模型:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。

方法二:(Thread+Handler)

查阅了文档和apidemo后,发觉常用的方法是利用Handler来实现UI线程的更新的。

Handler来根据接收的消息,处理UI更新。Thread线程发出Handler消息,通知更新UI。

Handler myHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case TestHandler.GUIUPDATEIDENTIFIER:
myBounceView.invalidate();
break;
}
super.handleMessage(msg);
}
};
class myThread implements Runnable {
public void run() {
while (!Thread.currentThread().isInterrupted()) {

Message message
= new Message();
message.what
= TestHandler.GUIUPDATEIDENTIFIER;

TestHandler.
this.myHandler.sendMessage(message);
try {
Thread.sleep(
100);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}

以上方法demo看:http://rayleung.javaeye.com/blog/411860

方法三:(java习惯,不推荐)

在Android平台中需要反复按周期执行方法可以使用Java上自带的TimerTask类,TimerTask相对于Thread来说对于资源消耗的更低,除了使用Android自带的AlarmManager使用Timer定时器是一种更好的解决方法。 我们需要引入import java.util.Timer; 和 import java.util.TimerTask;

public class JavaTimer extends Activity {

Timer timer
= new Timer();
TimerTask task
= new TimerTask(){
public void run() {
setTitle(
"hear me?");
}
};

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

timer.schedule(task,
10000);

}
}

方法四:(TimerTask + Handler)

实际上这样做是不行的,这跟Android的线程安全有关!应该通过配合Handler来实现timer功能的!

public class TestTimer extends Activity {

Timer timer
= new Timer();
Handler handler
= new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
setTitle(
"hear me?");
break;
}
super.handleMessage(msg);
}

};  

TimerTask task
= new TimerTask(){
public void run() {
Message message
= new Message();
message.what
= 1;
handler.sendMessage(message);
}
};  

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
 
timer.schedule(task, 10000);
}
}

方法五:( Runnable + Handler.postDelayed(runnable,time) )

在Android里定时更新 UI,通常使用的是 java.util.Timerjava.util.TimerTask, android.os.Handler组合。实际上Handler 自身已经提供了定时的功能。 

private Handler handler = new Handler();

private Runnable myRunnable= new Runnable() {
public void run() {

if (run) {
handler.postDelayed(
this, 1000);
count
++;
}
tvCounter.setText(
"Count: " + count);

}
};

然后在其他地方调用

handler.post(myRunnable);

handler.post(myRunnable,time);

案例看:http://shaobin0604.javaeye.com/blog/515820

====================================================================

知识点总结补充:

   很多初入Android或Java开发的新手对Thread、Looper、Handler和Message仍然比较迷惑,衍生的有HandlerThread、java.util.concurrent、Task、AsyncTask由于目前市面上的书籍等资料都没有谈到这些问题,今天就这一问题做更系统性的总结。我们创建的Service、Activity以及Broadcast均是一个主线程处理,这里我们可以理解为UI线程。但是在操作一些耗时操作时,比如I/O读写的大文件读写,数据库操作以及网络下载需要很长时间,为了不阻塞用户界面,出现ANR的响应提示窗口,这个时候我们可以考虑使用Thread线程来解决。

   对于从事过J2ME开发的程序员来说Thread比较简单,直接匿名创建重写run方法,调用start方法执行即可。或者从Runnable接口继承,但对于Android平台来说UI控件都没有设计成为线程安全类型,所以需要引入一些同步的机制来使其刷新,这点Google在设计Android时倒是参考了下Win32的消息处理机制。

 1. 对于线程中的刷新一个View为基类的界面,可以使用postInvalidate()方法在线程中来处理,其中还提供了一些重写方法比如postInvalidate(int left,int top,int right,int bottom) 来刷新一个矩形区域,以及延时执行,比如postInvalidateDelayed(long delayMilliseconds)或postInvalidateDelayed(long delayMilliseconds,int left,int top,int right,int bottom) 方法,其中第一个参数为毫秒

 2. 当然推荐的方法是通过一个Handler来处理这些,可以在一个线程的run方法中调用handler对象的 postMessage或sendMessage方法来实现,Android程序内部维护着一个消息队列,会轮训处理这些,如果你是Win32程序员可以很好理解这些消息处理,不过相对于Android来说没有提供 PreTranslateMessage这些干涉内部的方法。

3. Looper又是什么呢? ,其实Android中每一个Thread都跟着一个Looper,Looper可以帮助Thread维护一个消息队列,但是Looper和Handler没有什么关系,我们从开源的代码可以看到Android还提供了一个Thread继承类HanderThread可以帮助我们处理,在HandlerThread对象中可以通过getLooper方法获取一个Looper对象控制句柄,我们可以将其这个Looper对象映射到一个Handler中去来实现一个线程同步机制,Looper对象的执行需要初始化Looper.prepare方法就是昨天我们看到的问题,同时推出时还要释放资源,使用Looper.release方法。

4.Message 在Android是什么呢? 对于Android中Handler可以传递一些内容,通过Bundle对象可以封装String、Integer以及Blob二进制对象,我们通过在线程中使用Handler对象的sendEmptyMessage或sendMessage方法来传递一个Bundle对象到Handler处理器。对于Handler类提供了重写方法handleMessage(Message msg) 来判断,通过msg.what来区分每条信息。将Bundle解包来实现Handler类更新UI线程中的内容实现控件的刷新操作。相关的Handler对象有关消息发送sendXXXX相关方法如下,同时还有postXXXX相关方法,这些和Win32中的道理基本一致,一个为发送后直接返回,一个为处理后才返回 .

5. java.util.concurrent对象分析,对于过去从事Java开发的程序员不会对Concurrent对象感到陌生吧,他是JDK 1.5以后新增的重要特性作为掌上设备,我们不提倡使用该类,考虑到Android为我们已经设计好的Task机制,这里不做过多的赘述,相关原因参考下面的介绍:

6. 在Android中还提供了一种有别于线程的处理方式,就是Task以及AsyncTask,从开源代码中可以看到是针对Concurrent的封装,开发人员可以方便的处理这些异步任务。

posted @ 2012-04-11 17:04 Eric_jiang 阅读(891) | 评论 (1)编辑 收藏

在模拟器上获取GPS信息时,使用Location loc = LocationManager.getLastKnownLocation("gps");来获取location信息,但是往往在调试中locnull的,因为首先需要在模拟器中手动添加GPS信息,有两种手动添加方法
1、在eclipse下,windows-->open perspective-->DDMS-->Emulator control-->Manual下手动设置经纬度,并按send按钮。
2、在cmd下手动添加信息。
(1)首先打开模拟器,然后运行cmd,输入telnet localhost 5554(注:5554是模拟器在本机的端口,有可能不一样哈,具体端口号,模拟器左上方有显示的),这样会出现
Android Console: type 'help' for a list of commands
OK的字样。
如果是使用WIN7的朋友,控制台可能会提示telnet无效什么的,那是因为WIN7下默认是不出现telnet的,需要手动打开。具体为:[1]控制面板-->程序-->打开或关闭Windows功能,然后将Telnet服务器和Telnet客户端勾选上。[2]然后在管理工具-->服务中手动启动Telnet
(2)使用geo命令模拟发送GPS信号:
geo fix 经度 纬度
(3)这时就会发现在模拟器的状态栏上多了一个GPS的标志~再使用Location loc = LocationManager.getLastKnownLocation("gps");就能获取到该坐标的位置了~~
posted @ 2012-04-09 17:10 Eric_jiang 阅读(6132) | 评论 (0)编辑 收藏

仅列出标题
共57页: First 上一页 30 31 32 33 34 35 36 37 38 下一页 Last