Saturday, October 22, 2011

用VirtualBox開啟Android模擬器(Emulator is too slow)


撰寫時間︰2011/10/22 17:35
更新時間︰2012/02/08 16:41
文章更新次數︰3

話說我手上拿的筆電應該也不算差,
但是每次Android出一個新版,
模擬器開起來也就越吃力。

網路上查到了一個執行模擬器的方式,
那就是用VirtualBox去執行Android的ROM。
缺點也是有的︰
畢竟不是原本的Emulator,會有一些功能無法支援。
如︰重力感應。

在文章開始前,
有三件前置做頁需完成。
1.設好你的adb環境變數:Ubuntu的設定方式/Mac的設定方式
2.安裝好VirtualBox
3.下載Android ROM
Froyo版
Gingerbread版

步驟一、建立虛擬機器(Virtual Machine)
1.打開剛才安裝好的VirtualBox
2.點擊[新增]按鈕,此時會跳出精靈
    名稱輸入AndroidEmulator,作業系統︰Linux,版本︰Linux2.6-->[下一步]
    記憶體量設到512MB-->[下一步]
    啟動硬碟請打勾,然後選擇新建磁碟-->[下一步]
    選擇VHD(虛擬硬碟)-->[下一步]
    選擇固定大小-->[下一步]
    虛擬磁碟大小請設為2GB-->[下一步]-->[建立]
 虛擬機器設置完成

步驟二、設定虛擬機器基本功能

步驟1都做完後,回到VirtualBox主程式裡,點擊[設定值]做設定
1.設定Android ROM
選擇剛才你下載的Android ROM。


2.設定音效
如果沒設定到時候程式開起來是沒有聲音的
有些人是建議設定SoundBlaster 16,但是我設成Intel HD Audio才有聲音出來。

3.設定網路
沒有網路開起來的模擬器就無法上網
可惜的是我這麼設定還是上不了網(待確認)

最後,按下[確認]鍵,就設定完成啦!

步驟三、新增虛擬機器解析度的預設值
我們知道開發Android時會有各式各樣的解析度,
像是Sony和Moto常用的解析度854x480
HTC和Google常用的800x480/480x320
還有一些低階手機320x240
所以我們要將虛擬機器增加這些解析度預設值,
好讓之後啟動虛擬機器時,
我們可以直接用選擇的方式開啟我們要的畫面。

下圖是未設定的虛擬機大畫面。


1.修改AndroidEmulator.vbox檔
1)先開啟放置AndroidEmulator.vbox的資料夾

2)備份AndroidEmulator.vbox檔
3)將VirtualBox主程式完全關閉
4)用任何文件軟體將此檔打開,見下圖

將AndroidEmulator.vbox以純文字的方式打開後,找到<ExtraData>標籤區塊,
將以下這些內容覆蓋。
    <ExtraData>
      <ExtraDataItem name="CustomVideoMode1" value="240x320x16"/>
      <ExtraDataItem name="CustomVideoMode2" value="320x480x16"/>
      <ExtraDataItem name="CustomVideoMode3" value="480x800x16"/>
      <ExtraDataItem name="CustomVideoMode4" value="480x854x16"/>
      <ExtraDataItem name="GUI/LastCloseAction" value="powerOff"/>
      <ExtraDataItem name="GUI/LastGuestSizeHint" value="320,480"/>
      <ExtraDataItem name="GUI/LastNormalWindowPosition" value="402,159,320,526"/>
    </ExtraData>
注意︰
1.修改AndroidEmulator.vbox檔時,VirtualBox一定要先關閉,否則檔案會無法正常修改。
2.如果要設橫向畫面只要將前後數字顛倒並加入新的模式即可。
3.240x320x16裡的16代表16位元

步驟四、啟動虛擬機器
經過繁鎖的設定動作後,終於可以開啟虛擬機器了。
1.開啟AndroidEmulator
我們再次將VirtualBox程式打開,點選AndroidEmulator,點選上方工具列的[啟動]

在啟動時,可能會遇到底下的問題︰
有些電腦在第1次啟動AndroidEmulator時,
出現virtualbox android cannot access kernal driver的視窗錯誤。
解決辦法︰
1)先將VirtualBox關閉
2) 關閉防火牆跟防軟體 
3)進入C:\Program Files\Oracle\VirtualBox\drivers\vboxdrv資料夾,將底下vboxdrv.inf檔案點擊滑鼠右鍵,然後選擇安裝
4)重新啟動VirtualBox並啟動AndroidEmulator,問題解決!


2.將vga設成ask
開啟後,會見到下圖畫面
 選到VESA模式,按下Tab鍵
註︰如果需要hdpi環境(如︰800x480/854x480)請選擇第1個(HDPI模式) ,則選擇第1個選項並按下tab鍵


然後,我們將vga=xxx設成vga=ask,然後按下[Enter]鍵
註︰如果沒有vga=xxx則自己新增vga=ask

接下來,出現黑屏,見下圖
 我們按下ENTER鍵進入畫面設定

3.選擇畫面大小


我們看到了剛才修改AndroidEmulator.vbox後出現的值,我們現在想要開啟Emulator的尺寸是320x480x16,找了一下,代號為361,輸入後按下Enter鍵,模擬器啟動了。

這時候我們覺得奇怪,
滑鼠不見了!?

原來Virtual Machine將作業系統和虛擬機器的滑鼠分開了,
我們可以選擇[停用滑鼠整合]把這個區分關掉。
有看到[停用滑鼠整合]右邊的快速指令Host+I嗎?
Host指的就是右下角告訴你的這個熱鍵(範例裡是右側的Ctrl鍵)。
之後若要切換滑鼠在作業系統或是虛擬機器,只要按下右側的Ctrl+I鍵,就可以輕鬆切換了!

步驟五、將虛擬機器和Eclipse做連結
要怎麼讓Eclipse認識虛擬機器呢?
當然要下一些指令啦!

1.找出虛擬機的ip位置
1)回到虛擬機器的視窗(Ctrl+I),按下Alt+F1
這時候我們進入虛擬機器的終端機模式
2)輸入指令︰netcfg,然後按下Enter
取得虛擬機器的ip位置


2.在Windows的終端機(命令提示字元視窗)下下連結指令
得知虛擬機器的ip位置是192.168.11.54後,
我們將Windows的命令提示字元視窗開起來,
輸入以下指令
 adb connect <emulator’s IP address>
現在的例子是
adb connect 192.168.11.54
按下Enter鍵

命令提示字元應該要回覆你︰
connected to 192.168.11.54:5555

代表你和虛擬機器的連線成功了。

3.執行Eclipse

回到你的Eclipse專案中,點擊右鍵,
就會看到這個虛擬機器了。


回到虛擬機器,按下Alt+F7回到Android圖形化介面。
Enjoy it!

==================================
以上這篇說明你會用到的相關指令︰ 

在虛擬機器下
Alt+F1 切換至Android console畫面
Alt+F7 切換至Android圖形化介面
Host+I(Ctrl+I) 切換鼠標位置


相關文章︰
1.用手機開發Android程式 - 透過WiFi內網 (原標題︰SHIT!! 開發時忘了帶USB線!!)











Thursday, October 20, 2011

Database is locked

今天在修理別人的程式碼,
遇到一個錯誤︰
CREATE TABLE android_metadata failed
Failed to setLocale() when constructing, closing the database
android.database.sqlite.SQLiteException: database is locked

查了很多人的討論,
原因很多種,
但是對我現在的案子的原因是︰
兩個執行緒同時做了以下這件事

  if(mDatabaseHelper == null || mSQLiteDatabase == null) {
   DatabaseHelper mDatabaseHelper = new DatabaseHelper(mContext);
   mSQLiteDatabase = mDatabaseHelper.getWritableDatabase();
}
 

主要原因是同時間getWritableDatabase()
這樣的行為會導致 database is locked的錯誤。

Solution︰
在這段程式碼外圍加上synchronized,
讓執行緒能排隊執行,
避免2個執行緒同時都將mDatabaseHelper和 mSQLiteDatabase判斷成null而進入執行程式。

註︰Thread的運用真的要很小心!

Wednesday, October 19, 2011

在Mac建立Android的環境變數

開發Android時,
在終端機裡我們最常用到adb指令。
像是要從桌面快速安裝程式進手機裡︰adb install abc.apk
或者快速移除程式︰adb uninstall com.project.abc

我們不希望一直到android-sdk目錄底下去執行adb指令,
那該怎麼辦呢?
答案就是設定環境變數。

方法︰
開啟Finder-->你的名字的目錄-->.bash_profile檔

如︰simon-->.bash_profile

註︰.bash_profile是一個隱藏檔,
所以在找這個檔案前,
要先設定讓你的Finder可以看見隱藏檔。
如果找無此檔,請用文字編輯器創建一個起來即可。

Android因為adb指令和另一個常用的ddms指令在Android2.3以後,
已被分開放在不同目錄下,
所以必須在這個檔案裡新增︰
export PATH=${PATH}:/Users/simon/Android/android-sdk-mac_x86/platform-tools/
export PATH=${PATH}:/Users/simon/Android/android-sdk-mac_x86/tools/

註︰上面紅色那一段是你android-sdk的安裝位置。

存檔-->離開-->重開終端機-->大功告成!
註︰經回報不要使用文字編輯器修改這頁的內容,請使用vi或其它在timernal底下的文字編輯工具。

Friday, October 14, 2011

一個Eclipse匯入Android變紅XX的錯誤

案子在匯入後會變成紅色方型XX,
有非常多的理由。
通常我們都要在第1時間去看Console視窗裡寫些什麼錯誤訊息。


今天在匯入案子進筆電時,
發生了一個錯誤︰

[2011-10-15 14:25:00 - JeremyLiu] Dx
trouble processing "java/nio/CharBuffer.class":

Ill-advised or mistaken usage of a core class (java.* or javax.*)
when not building a core library.

This is often due to inadvertently including a core library file
in your application's project, when using an IDE (such as
Eclipse). If you are sure you're not intentionally defining a
core class, then this is the most likely explanation of what's
going on.

However, you might actually be trying to define a class in a core
namespace, the source of which you may have taken, for example,
from a non-Android virtual machine project. This will most
assuredly not work. At a minimum, it jeopardizes the
compatibility of your app with future versions of the platform.
It is also often of questionable legality.

If you really intend to build a core library -- which is only
appropriate as part of creating a full virtual machine
distribution, as opposed to compiling an application -- then use
the "--core-library" option to suppress this error message.

If you go ahead and use "--core-library" but are in fact
building an application, then be forewarned that your application
will still fail to build or run, at some point. Please be
prepared for angry customers who find, for example, that your
application ceases to function once they upgrade their operating
system. You will be to blame for this problem.

If you are legitimately using some code that happens to be in a
core package, then the easiest safe alternative you have is to
repackage that code. That is, move the classes in question into
your own package namespace. This means that they will never be in
conflict with core system classes. JarJar is a tool that may help
you in this endeavor. If you find that you cannot do this, then
that is an indication that the path you are on will ultimately
lead to pain, suffering, grief, and lamentation.

[2011-10-15 14:25:00 - JeremyLiu] Dx 1 error; aborting
[2011-10-15 14:25:00 - JeremyLiu] Conversion to Dalvik format failed with error 1

後來查了一下國外的論壇,才發現是專案在匯入Android的Jar檔時,Library Build錯位置了。

整個關鍵在於︰

 解決方式︰
Library標籤下應該會有一個android.jar(沒有放在Android2.2目錄下) ,
將其刪除,
並再將Android2.2Library匯入即可。