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 閱讀(1390) | 評論 (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 閱讀(5532) | 評論 (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 閱讀(492) | 評論 (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 閱讀(2254) | 評論 (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 閱讀(339) | 評論 (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 閱讀(2606) | 評論 (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 閱讀(1053) | 評論 (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 閱讀(9819) | 評論 (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 閱讀(907) | 評論 (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 閱讀(6145) | 評論 (0)編輯 收藏

          僅列出標題
          共57頁: First 上一頁 30 31 32 33 34 35 36 37 38 下一頁 Last 
          主站蜘蛛池模板: 揭西县| 柳河县| 封开县| 麦盖提县| 西充县| 会昌县| 江阴市| 汕尾市| 和龙市| 淮滨县| 潼关县| 广西| 兴隆县| 长泰县| 华安县| 九江县| 巴青县| 临颍县| 梅河口市| 柘荣县| 九龙城区| 西和县| 济南市| 同德县| 博罗县| 张家口市| 田阳县| 安平县| 永丰县| 册亨县| 东城区| 邹城市| 遵义市| 清苑县| 祁东县| 罗甸县| 西昌市| 通渭县| 宜良县| 庄浪县| 新宾|