2008年3月3日
#
j2me如何讀取網上資源文件例如文本文件,圖形文件。
例如,讀取www.kingdart.cn/jaccount/imobile.png 轉換為Image
又例如:讀取www.kingdart.cn/jaccount/readme.txt 轉換為String
只在模擬器上成功我也會,要求是真機上成功!
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/174850
發表時間: 2008年03月22日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
我的錯!在沒有認真閱讀FileConnection文檔之后就妄下結論.最近下載了fileconnection_spec_1.00文檔,發現其中有一個方法
public java.io.OutputStream openOutputStream(long byteOffset)
throws java.io.IOException
該方法在打開輸出流時可指定寫入的位置,寫入的數據將覆蓋舊數據,利用這個方法,還是有可能在手機上實現文件式RMS的.
現在我正在做手機理財JAccount的文件備份和恢復,還分不出身來嘗試,有興趣的朋友可以自已試一下如果OK了,別忘了告訴我一聲哦!
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/174850
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/174754
發表時間: 2008年03月22日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
由于要為手機理財JAccount增加數據導出到文本文件功能,我為其增加了exportToFile(String fileName)方法,使用Moto模擬器(A630)時發現裝入JAR階段已出錯,錯誤的信息是:
ALERT: Unable to load class javax/microedition/io/file/FileConnection,RAZR_V3則正常.要知道,我從未打算為不同的手機制作不同的JAR,我計劃是在代碼中檢查該手機是否支持FileConnection,若支持的話,菜單項才增加備份和恢復命令項.
如果所有不支持FileConnection的手機都不能裝入的話,那不是只能為支持的開發一個版本,不支持的又開發另一個版本?
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/174754
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/174645
發表時間: 2008年03月21日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
/**
* --------------------------------------------------
* 字段輸入流
* --------------------------------------------------
* 從DataInputStream繼承
* 主要增加了從文本格式輸入流中讀入數據字段的能力
* --------------------------------------------------
*
* @author iwinyeah 李永超
* @version 1.0.0
* */
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
public class FieldInputStream extends DataInputStream {
public final static int BIN_MODE = 0;
public final static int TXT_MODE = 1;
int mode;
public FieldInputStream(InputStream in, int mode) {
super(in);
this.mode = mode;
}
public boolean getBoolean() throws IOException {
if (mode == 0) {
return readBoolean();
} else {
if ("1".equals(next())) {
return true;
}
return false;
}
}
public byte getByte() throws IOException {
if (mode == 0) {
return readByte();
} else {
return (byte) Integer.parseInt(next());
}
}
public short getShort() throws IOException {
if (mode == 0) {
return readShort();
} else {
return (short) Integer.parseInt(next());
}
}
public int getInt() throws IOException {
if (mode == 0) {
return readInt();
} else {
return Integer.parseInt(next());
}
}
public long getLong() throws IOException {
if (mode == 0) {
return readLong();
} else {
return Long.parseLong(next());
}
}
public String getString() throws IOException {
if (mode == 0) {
if (read() == 0) {
return null;
} else {
return readUTF();
}
} else {
return next();
}
}
// 取下一標識符
private byte[] buffer = new byte[255];
private int length = 0;
private boolean eos = false;
private final static int INITIAL = 0;
private final static int ESCAPE = 1;
private final static int COMMENT_START = 2;
private final static int LINE_COMMENT = 3;
private final static String WHITESPACE = "\n\r\t";
public String next() throws IOException {
length = 0;
int c = in.read();
int status = INITIAL;
READWHILE: while (c != -1) { // 一直讀到文件尾
switch (status) {
case INITIAL:
if (c == '\n' || c == '\t') { // 如果是分隔符
break READWHILE;
} else if (c == '\\') {
status = ESCAPE; // 設轉義字符標志
} else if (c == '/') {
status = COMMENT_START; // 設注釋標志
} else {
if (WHITESPACE.indexOf(c) < 0) {
append(c);
}
}
break;
case ESCAPE: // 處理轉義字符
switch (c) {
case 'n':
append('\n');
break;
case 'r':
append('\r');
break;
case 't':
append('\t');
break;
case 'b':
append('\b');
break;
case 'f':
append('\f');
break;
default:
append(c);
break;
}
status = INITIAL; // 設正常情況標志
break;
case COMMENT_START: // 處理注釋
if (c == '/') {
status = LINE_COMMENT; // 是行式注釋
} else {
status = INITIAL;
// 如果都不是則把注釋起始符和剛讀入的字符都加入到標識符中
append('/');
append(c);
}
break;
case LINE_COMMENT:
if (c == '\n') {
status = INITIAL; // 如果當前為行注釋狀態則要一直讀到行尾才恢復正常情況標志
break READWHILE;
}
break;
}
c = in.read(); // 讀入下一字符
}
if (c == -1) {
eos = true;
}
// 如果讀到文件尾時,標識符長度大于零,則返回標識符,否則返回NULL值
if (length <= 0) {
return null;
} else {
return new String(buffer, 0, length, "UTF-8");
}
}
// 將讀入的字符加入緩沖區
private void append(int c) {
// 緩沖區不足時自動擴展
if (length >= buffer.length) {
byte[] xBuffer = new byte[buffer.length + 16];
System.arraycopy(buffer, 0, xBuffer, 0, buffer.length);
buffer = null;
buffer = xBuffer;
}
buffer[length++] = (byte) c;
}
public boolean eos() {
return eos;
}
}
請參看我的另一篇文章:字段輸出流FieldOutputStream
http://iwinyeah.javaeye.com/admin/blogs/174644
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/174645
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/174644
發表時間: 2008年03月21日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
我的FieldOutputStream繼承了DataOutputStream,這樣就可以只更改很少量的代碼就實現了既支持原生格式又支持文本方式輸出了,稍候一段時間手機理財將可以實現備份和恢復(文本格式)功能了.
package util;
/**
* --------------------------------------------------
* 字段輸出流
* --------------------------------------------------
* 從DataOutputStream繼承
* 主要增加了向輸出流寫入文本格式的數據字段的能力
* 文本格式流將由TAB分隔字段,回車換行符分隔記錄
* --------------------------------------------------
*
* @author iwinyeah 李永超
* @version 1.0.0
* */
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class FieldOutputStream extends DataOutputStream {
public final static int BIN_MODE = 0;
public final static int TXT_MODE = 1;
private final static byte[] fieldSplit = {'\t'};
private final static byte[] recordSplit = {'\r','\n'};
private int mode;
private boolean nextEnd = false;
public FieldOutputStream(OutputStream out, int mode) {
super(out);
this.mode = mode;
}
// 接著寫入的是否最后一個字段
// 寫第一個字段前以參數false調用它
// 寫最后一個字段前以參數false調用它
public void setNextEnd(boolean end){
nextEnd = end;
}
public void putBoolean(boolean value) throws IOException {
if (mode == 0) {
writeBoolean(value);
} else {
out.write(value ? '1' : '0');
out.write(nextEnd ? recordSplit : fieldSplit);
}
}
public void putByte(byte value) throws IOException {
if (mode == 0) {
writeByte(value);
} else {
out.write(String.valueOf(value).getBytes("UTF-8"));
out.write(nextEnd ? recordSplit : fieldSplit);
}
}
public void putShort(short value) throws IOException {
if (mode == 0) {
writeShort(value);
} else {
out.write(String.valueOf(value).getBytes("UTF-8"));
out.write(nextEnd ? recordSplit : fieldSplit);
}
}
public void putInt(int value) throws IOException {
if (mode == 0) {
writeInt(value);
} else {
out.write(String.valueOf(value).getBytes("UTF-8"));
out.write(nextEnd ? recordSplit : fieldSplit);
}
}
public void putLong(long value) throws IOException {
if (mode == 0) {
writeLong(value);
} else {
out.write(String.valueOf(value).getBytes("UTF-8"));
out.write(nextEnd ? recordSplit : fieldSplit);
}
}
public void putString(String value) throws IOException {
if (mode == 0) {
if (value == null) {
writeByte(0);
} else {
writeByte(1);
writeUTF(value);
}
} else {
if(value != null){
byte[] b = value.getBytes("UTF-8");
for(int i = 0; i < b.length; i++){
if(b[i] == '\n'){
out.write('\\');
out.write('n');
}
else if(b[i] == '\r'){
out.write('\\');
out.write('r');
}
else if(b[i] == '\t'){
out.write('\\');
out.write('t');}
else if(b[i] == '\b'){
out.write('\\');
out.write('b');}
else if(b[i] == '\f'){
out.write('\\');
out.write('f');
}else{
out.write(b[i]);
}
}
}
out.write(nextEnd ? recordSplit : fieldSplit);
}
}
}
讀回請參看另一篇:字段輸入流FieldInputStream.
http://iwinyeah.javaeye.com/admin/blogs/174645
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/174644
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/173704
發表時間: 2008年03月19日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
我的一個日期處理類,解決了時區問題,給有需要的人。
package util;
/**
* --------------------------------------------------
* 日期轉換對象
* --------------------------------------------------
* 主要提供日期與1970-01-01后的天數的轉換和到字符串的轉換
* --------------------------------------------------
*
* @author iwinyeah 李永超
* @version 1.0.0
* */
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class DateUtil {
private static Calendar _calendar = Calendar.getInstance(); // 用于日期計算
private static long MSEC_EVERYDAY = 86400000L; // 一天的微秒數
private static int rawOffset = TimeZone.getDefault().getRawOffset();
/**
* 將日期轉換為1970-01-01后的天數
*
* @param Date
* theDate 要計算天數的日期
* @return int 所傳入日期與1970-01-01相差的天數
*/
public static int dateToDay(Date theDate) {
return (int) ((theDate.getTime() + rawOffset) / MSEC_EVERYDAY);
}
/**
* 將1970-01-01后的天數轉換為日期
*
* @param int
* 要取的日期與1970-01-01相差的天數
* @return Date theDate 與1970-01-01相差相應天數的日期
*/
public static Date dayToDate(int day) {
return new Date(day * MSEC_EVERYDAY);
}
/**
* 取今天與1970-01-01相差的天數
*
* @return int 取今天與1970-01-01相差的天數
*/
public static int toDay() {
return (int) ((System.currentTimeMillis() + rawOffset) / MSEC_EVERYDAY);
}
/**
* 將日期轉換為年月日字符串
*
* @param int
* theDay 與1970-01-01相差的天數
* @return String 對應日期年月日形式的字符串
*/
public static String getYMD(int theDay) {
_calendar.setTime(dayToDate(theDay));
return _calendar.get(Calendar.YEAR) % 100 + "/"
+ (_calendar.get(Calendar.MONTH) + 1 > 9 ? "" : "0")
+ (_calendar.get(Calendar.MONTH) + 1) + "/"
+ (_calendar.get(Calendar.DATE) > 9 ? "" : "0")
+ _calendar.get(Calendar.DATE);
}
/**
* 將日期轉換為年月字符串
*
* @param int
* theDay 與1970-01-01相差的天數
* @return String 對應日期年月形式的字符串
*/
public static String getYM(int theDay) {
_calendar.setTime(dayToDate(theDay));
return _calendar.get(Calendar.YEAR) + "/"
+ (_calendar.get(Calendar.MONTH) + 1 > 9 ? "" : "0")
+ (_calendar.get(Calendar.MONTH) + 1);
}
/**
* 將日期轉換為月日字符串
*
* @param int
* theDay 與1970-01-01相差的天數
* @return String 對應日期月日形式的字符串
*/
public static String getMD(int theDay) {
_calendar.setTime(dayToDate(theDay));
return (_calendar.get(Calendar.MONTH) + 1 > 9 ? "" : "0")
+ (_calendar.get(Calendar.MONTH) + 1) + "/"
+ (_calendar.get(Calendar.DATE) > 9 ? "" : "0")
+ _calendar.get(Calendar.DATE);
}
/**
* 將日期轉換為當月一號
*
* @param int
* theDay 與1970-01-01相差的天數
* @return int 對應日期所在月份第一天與1970-01-01相差的天數
*/
public static int getMonthFirstDay(int theDay) {
_calendar.setTime(dayToDate(theDay));
_calendar.set(Calendar.DAY_OF_MONTH, 1);
return (int) (dateToDay(_calendar.getTime()));
}
/**
* 取日期所在年份
*
* @param int
* theDay 與1970-01-01相差的天數
* @return int 對應日期所在年份
*/
public static int getYear(int theDay) {
_calendar.setTime(dayToDate(theDay));
return _calendar.get(Calendar.YEAR);
}
/**
* 取日期所在月份
*
* @param int
* theDay 與1970-01-01相差的天數
* @return int 對應日期所在月份
*/
public static int getMonth(int theDay) {
_calendar.setTime(dayToDate(theDay));
return _calendar.get(Calendar.MONTH);
}
/**
* 取日期所在周次
*
* @param int
* theDay 與1970-01-01相差的天數
* @return int 對應日期所在周次
*/
public static int getWeek(int theDay) {
// 1971-01-03是星期日,從該日開始計算周次
_calendar.setTime(dayToDate(theDay));
return (int) ((_calendar.getTime().getTime() - 172800000L) / 604800000L);
}
}
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/173704
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/172974
發表時間: 2008年03月17日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
Action: 規定了與用戶交互的View可以觸發的動作,在某個View新建之后顯示之前,應先為其指定具體的Action,當用戶按下了相應的Command按鈕之后,View將該Command對應的Action發送到該View的Controller進行處理。
//
public class Action{
String name; // 名稱
Command command; // 命令
int code; // 代碼 (將由該View的傳遞到其Controller使用)
Item item; // 數據項
boolean defaultAction; // 是否是默認的Action
//...省略
}
請看View的基類的代碼節選
public abstract class AbstractView{
//...省略
// 為該View增加Action
public void addAction( final Action action, final boolean active )
{
if( !actions.containsKey( action.getName() ) )
{
// 將Action存入Actions表中
actions.put( action.getName(), action );
if( active )
{
activateAction( action );
}
}
}
// 使Action生效可用
private void activateAction( final Action action )
{
final Command command = action.getCommand();
activeActions.put( command, action );
final Item item = action.getItem();
if( item == null )
{
addCommand( command ); // 該Action是屏幕相關的命令
}
else
{
item.addCommand( command ); // 該Action是數據項相關的命令
if( action.isDefaultAction() )
{
item.setDefaultCommand( command );
}
}
}
//...省略
// 用戶按下相應的命令鍵后,觸發執行與其關聯的Action
public void commandAction(
final Command command,
final Displayable displayable
)
{
if( !handleAction( command ) )
{
if( displayable instanceof Choice )
{
AbstractController.commandAction(
this,
command,
(Choice) displayable
);
}
else
{
AbstractController.commandAction( this, command );
}
}
}
// 用戶在某個指定了命令的Item按下了命令按鈕時觸發執行與其關聯的Action
public void commandAction( final Command command, final Item item )
{
if( !handleAction( command ) )
{
AbstractController.commandAction( this, command );
}
}
// 根據所觸發的命令查找關聯的Action,并新它發送到Controller進行處理
public boolean handleAction( final Command command )
{
if( activeActions.containsKey( command ) )
{
final Action action = (Action) activeActions.get( command );
// 以Action代碼為參數生成ControllerEvent并傳遞到controller處理
final ControllerEvent event = new ControllerEvent(
action.getCode(),
this
);
controller.handle( event );
return true;
}
else
{
return false;
}
}
//...省略
}
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/172974
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/172237
發表時間: 2008年03月15日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
經過多次的嘗試,終于解決了手機理財JAccount在Nokia 6070反復統計收支表和余額表時出錯的問題.
原來我有兩個報表上分別使用了incomeVector 和balanceVector來保存所生成的統計資料,每次統計前檢查Vector是否為null,否則先置空,再重新new一個.
我嘗試過new之后加了runtime.gc(),未能解決問題;
我又嘗試過不置空Vector,而使用vector.removeallelements(),也不行;
我又嘗試過兩個報表共用一個Vector也不行;
最后,我使用兩個報表共用數組來保存結果,才解決了問題,有點開心.
類似Nokia6070這種機器的JVM的內存管理的確存在很大的問題,明明有內存也用不得,真郁悶!
不過還是有點開心,畢竟解決了一個問題!
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/172237
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/172200
發表時間: 2008年03月15日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
我以前在其他地方發過的貼子,這幾種方式都沒問題,哪種較好或者說在什么情況下用哪種方法較好呢?
// 方法一
public class firstManager implements Runnable {
public void runTask() {
(new Thread(this)).start();
}
public void run() {
System.out.println("\nfirst thread method!");
// Do some thing ...
}
}
// 方法二
public class secondManager {
private BackTask backTask;
private Timer timer;
public secondManager() {
backTask = new BackTask();
timer = new Timer();
}
public void runTask() {
timer.schedule(backTask, 0);
}
private class BackTask extends TimerTask {
public void run() {
System.out.println("\nsecond thread method!");
// Do some thing ...
}
}
}
// 方法三
public class thirdManager {
private BackTask backTask;
private int cmd = 0;
public thirdManager() {
backTask = new BackTask();
backTask.start();
}
public void runTask() {
synchronized (backTask) {
cmd = 1;
backTask.notify();
}
}
private class BackTask extends Thread {
public void run() {
while (true) {
try {
if (cmd == 0) {
synchronized (this) {
wait();
}
continue;
}
System.out.println("\nthird thread method!");
// Do some thing ...
} catch (Exception e) {
}
cmd = 0;
}
}
}
}
// 用例
public void main(){
firstManager man1 = new firstManager();
secondManager man2 = new secondManager();
thirdManager man3 = new thirdManager();
man1.runTask();
man2.runTask();
man3.runTask();
}
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/172200
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/170335
發表時間: 2008年03月12日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
在處理資源文件時,我以前的做法是一次性讀入資源文件,然后再進行處理,在處理大文件時,這種方法對由于對機器內存消耗較大而存在隱患,剛想將它改為逐字讀入的方式,在OpenBaseMovil中發現了這個類,很符合我的要求。關鍵代碼如下:
//... 省略
public static final String WHITESPACE = "\r\n\t ";
public String next(final String delimiters, final boolean keepWhitespace,
final boolean allowComments, final boolean reuseDelimiter,
final boolean processEscape) throws IOException {
try {
final StringBuffer token = new StringBuffer();
startLine = endLine;
startChar = endChar;
int c = in.read();
endChar++;
int status = INITIAL;
while (c != -1) { // 若還未讀到文件尾
if (c == '\n') {
endLine++;
endChar = 0;
}
switch (status) {
case INITIAL:
if (delimiters.indexOf(c) > -1) { // 如果是分隔符
lastDelimiter = (char) c;
if (isWhiteSpace(c)) {
// 如果同時也是空白符并且標識符長度大于零則返回標識符
if (token.length() > 0) {
if (reuseDelimiter) { // 如果要重用分隔符則將它推回輸入流中
in.revert((char) c);
}
return token.toString();
}
// 如果還未有數據,還要繼續往下讀
} else { // 如果不是空白符則無論標識符長度是否為零,都要返回
if (reuseDelimiter) {
in.revert((char) c);
}
return token.toString();
}
} else if (processEscape && c == '\\') {
status = ESCAPE; // 設轉義字符標志
} else if (allowComments && c == '/') {
status = COMMENT_START; // 設注釋標志
} else if (isWhiteSpace(c)) {
if (keepWhitespace) { // 如果空白符也要用,把它加入標識符中
token.append((char) c);
}
} else {
token.append((char) c);
}
break;
case ESCAPE: // 處理轉義字符
switch (c) {
case 'n':
token.append('\n');
break;
case 'r':
token.append('\r');
break;
case 't':
token.append('\t');
break;
case 'b':
token.append('\b');
break;
case 'f':
token.append('\f');
break;
default:
token.append((char) c);
break;
}
status = INITIAL; // 設正常情況標志
break;
case COMMENT_START: // 處理注釋
if (c == '/') {
status = LINE_COMMENT; // 是行式注釋
} else if (c == '*') {
status = BLOCK_COMMENT; // 是塊式注釋
} else {
status = INITIAL;
// 如果都不是則把注釋起始符和剛讀入的字符都加入到標識符中
token.append('/').append((char) c);
}
break;
case LINE_COMMENT:
if (c == '\n') {
status = INITIAL; // 如果當前為行注釋狀態則要一直讀到行尾才恢復正常情況標志
}
break;
case BLOCK_COMMENT:
if (c == '*') {
status = COMMENT_END; // 如果當前為塊注釋狀態則要一直讀到*號設為塊注釋結束狀態
}
break;
case COMMENT_END:
if (c == '/') {
status = INITIAL; // 在塊結束狀態下讀到/則為塊結束
} else {
status = BLOCK_COMMENT; // 否則塊注釋還未結束,恢復為塊注釋狀態
}
break;
}
c = in.read(); // 讀入下一字符
}
// 如果讀到文件尾時,標識符長度大于零,則返回標識符,否則返回NULL值
return token.length() > 0 ? token.toString() : null;
} catch (IOException e) {
throw new IOException("Error reading input L=" + startLine + " C="
+ startChar);
}
}
//... 省略
不過從代碼可以看出,它并不支持非Ascii編碼格式的文件,還要進行進一步的改造。
我的計劃是StringBuffer 用byte[]代替,增加setEncode(String encode)方法,返回字符串時使用 new String(byte[], encode)
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/170335
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/170016
發表時間: 2008年03月11日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
對于手機理財JAcount,我在SE K750, SE P990,Philips768, Nokia2630上進行過完整的測試,都沒有什么問題.最近,在移動那里一元購機了一臺Nokia6070,原以為與Nokia2630一樣是S40的機器,應該沒什么問題,結果余額表和收支表重復算兩次后出現了"應用程序錯誤",詳情是Array Index out of bounds,我估計是內存不足,于是在重新開啟程序,打開了第一次收支表后檢查了內存,還有300多K,再次打開收支表,又出錯了,還未搞清楚是什么原因,真有點失敗的感覺,前一段時間在聊天時借了別人的Nokia N73,結果安裝時候就死機了,還沒機會檢查是什么問題,現在先弄好Nokia 6070的問題吧.唉!兼容性!
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/170016
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/169545
發表時間: 2008年03月09日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
唉,有貼代碼騙糧票的嫌疑呢,至少大家可以在這里看到各種設備的規格方法了.
public static boolean isBlackBerry()
{
return checkPlatform( "RIM" );
}
public static boolean checkPlatform( final String key )
{
final String platform = System.getProperty( "microedition.platform" );
return platform != null && platform.toUpperCase().indexOf(
key.toUpperCase()
) > -1;
}
public static boolean checkUserAgent( final String key )
{
final String userAgent = Application.getManager().getProperty(
"user-agent"
);
return userAgent != null && userAgent.toUpperCase().indexOf(
key.toUpperCase()
) > -1;
}
public static boolean checkPlatform( final String[] keys )
{
final int length = keys.length;
for( int i = 0; i < length; i++ )
{
if( checkPlatform( keys[i] ) )
{
return true;
}
}
return false;
}
public static boolean isNokia()
{
return checkPlatform( "Nokia" );
}
public static boolean isEmulator()
{
return checkPlatform( new String[] { "j2me", "SunMicrosystems_wtk" } );
}
public static boolean isSonyEricsson()
{
return checkPlatform( "SonyEricsson" );
}
public static boolean isSonyEricssonJP7()
{
return isSonyEricsson() && checkPlatform( JP7 );
}
public static boolean isSymbian()
{
return checkUserAgent( "SymbianOS" );
}
public static boolean isSeries60()
{
return checkUserAgent( "Series60" );
}
public static boolean isSeries60_2nd()
{
return checkUserAgent( "Series60/2" );
}
public static boolean isSeries60_3rd()
{
return checkUserAgent( "Series60/3" );
}
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/169545
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/169280
發表時間: 2008年03月08日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
public void main(){
Integer nullInt = null;
tryChangeInteger(nullInt);
if(nullInt == null){
System.out.println("\nThe Object nullInt not be changed.");
}else{
System.out.println("\nThe Object nullInt now is " + nullInt);
}
}
private void tryChangeInteger(Integer theInt){
theInt = new Integer(100);
}
// 控制臺應打印出什么呢?(The Object nullInt not be changed.)
//
// 關鍵要理解好Java的參數傳遞是傳值而不是傳引用,因而在tryChangeInteger方法
// 里得到的theInt不是main方法里的nullInt,而是nullInt的副本,nullInt值并沒有被改變。
// 再請看以下代碼
public void main() {
char[] initChars = new char[10];
initChars[0] = 'a';
tryChangeCharArray(initChars);
if(initChars[0] == 'a'){
System.out.println("\nThe Object initChars[0] not be changed.");
}else{
System.out.println("\nThe Object initChars[0] now is " + initChars[0]);
}
}
private void tryChangeCharArray(char[] theChars){
if(theChars != null && theChars.length > 0){
theChars[0] = 'b';
}
}
// 控制臺應打印出什么呢?(The Object initChars[0] now is b")
// Why?
// 弄明白了這個,JAVA引用基本就明白了。
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/169280
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/168955
發表時間: 2008年03月07日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
以下代碼由bm.core.tools.DeviceInfo.java抽出,詳見該文件
private void testFontListBug()
{
if( isNokia() )
{
// 就算是Nokia的設備也要進行一下測試來確定是否有這個Bug
final Font font = Font.getFont(
Font.FACE_PROPORTIONAL,
Font.STYLE_PLAIN,
Font.SIZE_SMALL
);
final List list = new List( "", List.IMPLICIT );
for( int i = 0; i < 3; i++ )
{
list.append( "", null );
}
for( int i = 0; i < 3; i++ )
{
list.setFont( i, font );
}
list.deleteAll();
try
{
for( int i = 0; i < 4; i++ )
{
list.append( "", null );
}
listFontBug = false;
}
catch( Throwable e )
{
listFontBug = true;
}
}
else
{
// 除Nokia設備外,其它設備都假定它有這個Bug
// 不知道實際上是不是這樣呢?我估計大部分的手機都有這個問題
// 不然他不會這么做
listFontBug = true;
}
}
那么這個Bug是什么呢?
我在bm.mvc.ListBrowserView中找到如下代碼:
if( !DeviceInfo.getDeviceInfo().hasListFontBug() )
{
final int itemCount = list.size();
for( int i = 0; i < itemCount; i++ )
{
list.setFont( i, Util.SMALL_FONT );
}
}
也就是說,有這個Bug的設備不能將List的項的字體更改為SMALL_FONT
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/168955
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/168522
發表時間: 2008年03月06日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
private void doShow()
{
// This delays minimze the chance that a Nokia 6670 or Nokia S60 3rd
// edition device (might apply to other nokias) freez when showing a
// view. The total delay of 600ms, with this distribution seems to
// make it stable on E70 and E61. The delay is only applied to Nokia
// phones at this moment
if( displayable != null )
{
final Display display = Application.getManager().getDisplay();
delay();
delay();
display.setCurrent( displayable );
if( !DeviceInfo.isNokia() && focusedItem != null )
{
delay();
delay();
display.setCurrentItem( focusedItem );
}
setCurrent( this );
delay();
delay();
}
}
private void delay()
{
if( delay )
{
// Under some strange circumstances the Nokia 6670 crashes whitout this delay
try
{
Thread.sleep( 100 );
}
catch( InterruptedException e )
{
}
}
}
是否的確是這樣?天啊,誰可以使用以上環境的設備給我測試一下我的手機理財JAccount呢?
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/168522
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/168521
發表時間: 2008年03月06日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
如果你用Eclipse開發java應用的話,我強烈建議你安裝它,這樣,你隨時可解開jar文件瀏其他人特別是SUN公司的源代碼了(SUN的JAR沒有經過混淆),對于學習java是十分有益而高效的.
Eclipse/軟件更新/查找與安裝/新建遠程站點/地址為:http://www.technoetic.com/eclipse/update
安裝完成后,要使用時,在包資源管理器上列出你要查看的class,雙擊該文件,會出現錯誤提示,不理它,再雙擊一次就可以在編輯器上出現源代碼了!超方便!
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/168521
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/168482
發表時間: 2008年03月05日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
一個簡單的高速對象緩存
public class SimpleCache
{
private static long wideHits;
private static long wideMisses;
private Hashtable cache;
private Vector stamps;
private int maxSize;
private long hits;
private long misses;
// ...部分省略
// 構建函數,根據SIZE構建Cache和命中表
public SimpleCache( final int size )
{
this.maxSize = size;
cache = new Hashtable( size );
stamps = new Vector( size );
}
// ...部分省略
public void add( final Object key, final Object object )
{
// 為什么不直接使用cache而要使用另一個引用?
final Hashtable cache = this.cache;
if( !cache.containsKey( key ) )
{
if( cache.size() == maxSize )
{
discard(); // 如果Cache超過容量,按策略丟棄過時的對象
}
// 在Cache中加入這個對象
cache.put( key, object );
// 相應也插入命中表第一位
stamps.insertElementAt( key, 0 );
}
else
{
// 更新Cache
cache.put( key, object );
// 也算命中一次
touch( key );
}
}
// ...部分省略
public synchronized Object get( final Object key )
{
final Object o = cache.get( key );
if( o != null )
{
hits++;
wideHits++;
// 算命中一次
touch( key );
}
else
{
misses++;
wideMisses++;
}
return o;
}
// ...部分省略
// 總是丟棄最后一個對象,
private void discard()
{
final Object key = stamps.lastElement();
stamps.removeElement( key );
cache.remove( key );
}
// 每次從Cache取用某key對象,都將它插到第一位
// 這樣不常用的對象將很快會被推至最后一位
private void touch( final Object key )
{
stamps.removeElement( key );
stamps.insertElementAt( key, 0 );
}
}
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/168482
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/167866
發表時間: 2008年03月04日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
感謝Cavaj!在Eclipse在包資源管理器上查到RecordStore.class在midpapi10.jar中
將C:\WTK22\lib\midpapi10.jar解開,然后用Cavaj!反編譯RecordStore.class,得到了兩個類,果然有些料到,不僅有記錄鏈表,還有自由鏈表,自由空間重用與分裂...,用代碼說話(個人做了一些修改和注釋)!
------------------------
寫在最后:原來研究它的目的是在利用J2me可選包FileConnection方式來實現手機理財JAccount
http://iwinyeah.javaeye.com/admin/categories/27410,但經分析后,FileConnection沒有實現skip()方法,換言之,不能對文件進行自由讀寫,因而該計劃也落了空.
在此也感謝無花
http://wuhua.javaeye.com/的提醒,的確,手機實現的FileConnection的安全檢查太多了,嚴重影響用戶體驗,不太合適用于這種方式的應用.
新計劃是手機理財JAccount上增加備份與恢復功能(read和append方式是FileConnection所支持的)由于備份和恢復無須經常地使用,用戶也可接受.
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/167866
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/167074
發表時間: 2008年03月03日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
有一個英語學習的圈子,我不想加入,看到有人要記單詞,我也把我的方法寫在下面:
個人經驗:找一本7000單詞的字典,約100頁左右,每天反復記1頁,未記好的用鉛筆打上標記,第二天先復習以前打上標記的單詞,已會的,將標記刷掉,然后記新一頁,如此堅持,100天基本可記住7000單詞,然后加快速度,每天4頁,再記一次,則功成矣!
看來,弄一個手機記單詞的軟件也許不錯呢,難度不大,如果真正有用,也許有一定市場呢,畢竟學生是消費力很強的群體.
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/167074
網站:
JavaEye
作者:
iwinyeah
鏈接:
http://iwinyeah.javaeye.com/blog/167071
發表時間: 2008年03月03日
聲明:本文系JavaEye網站發布的原創博客文章,未經作者書面許可,嚴禁任何網站轉載本文,否則必將追究法律責任!
Event事件對象: 有如下屬性:
protected Integer type; // 事件類型,預定義了全局事件,改變語言事件和進度事件
protected boolean consumed; // 事件是否已被處理
protected Hashtable attachments; // 以哈希表表示的與事件相關的對象附件
通過在靜態事件對象預先登記多個各種類型的事件監聽器,當有事件發生時,就可通過殂態事件對象將事件發送給事件監聽器進行處理.事件監聽器收到事件后,可根據事件類型和附件作出響應,如果不想在它之后登記的監聽器再處理該事件,則將consumed設置為true.
代碼如下:
public static void dispatch( final Event event )
{
// 以下還未明白什么意義
// 如果是進度事件并且當前的線程已在后臺任務中登記則不處理?
if(
!event.type.equals( PROGRESS ) ||
!backgroundTasks.contains( Thread.currentThread() )
)
{
final Vector v = (Vector) listeners.get( event.type );
if( v != null )
{
final int count = v.size();
for( int i = 0; i < count && !event.consumed; i++ )
{
final EventListener listener = (EventListener) v.elementAt( i );
listener.handleEvent( event );
Thread.yield();
}
event.consumed = false;
}
}
}
本文的討論也很精彩,瀏覽討論>>
JavaEye推薦
文章來源:
http://iwinyeah.javaeye.com/blog/167071