Corona SDK 入門 part 1

Corona 是一個跨手機平台的SDK, 有免費版及付費版. 若你打算上架App Store, 就一定要用付費版. 官網

理論上可以用在商業程式或遊戲, 看過API後我認為比較偏遊戲開發.

Corona用的是Lua language, 是一種直譯語言, 在遊戲界應該尚算流行. 弱型別語言, 可以用類似物件導向的寫法, 但我覺得還是偏非物件導向, 要封裝及傳遞變數並不是很直覺.

開發環境我是用LDT, 設定上不算複雜, 但也繼承了一些Eclipse的毛病, 總是會遇到問題. 設定方法如下

1) Add a new interpreter for corona simulator in the Lua/interpreter preference page by selecting "add" and selecting the Corona Simulator 
executable as Interpreter executable, adding "-debug" to "Interpreter arguments" and uncheck the option "Accept -e as argument". 
2013-12-16_0004392013-12-16_000453 
2) You should still add the following code at the begging of your project: 
if (system.getInfo("environment")=="simulator") then
require("debugger")()
end 
2013-12-16_000630
3) Copy the debugger.lua file by clicking on the top menu
"Run/Debug Configuration" and then create a "Lua Attach to application"
launch configuration and click on the link "Lua Debbuger Client" and
select "Corona SDK/Ressources" folder. 
2013-12-16_000803
4) Then go to top menu "Run/Debug Configuration" and create a "Lua Application" launch configuration which will use the created Corona interpreter 
as runtime interpreter and launch it in debug mode.
2013-12-16_000837

來源

啟動LDT時記得用管理員權限, 不然你做上面4 steps時會有問題

UPDATE : Corona Editor 1.0 已推出, 自動完成功能 樂勝

每一個程式都要有main.lua, 裡面的variable 雖然用local宣告, 但我看文件覺得那其實是global. 因為Lua不需要main function, 所以main.lua裡的local, 其實整個main都可以用得到.

至於其他檔案看不看得到?要怎樣定義類別及分檔案?這就是我覺得lua很不物件導向的原因, part 2再續…

Android 開發Part4

.R

Android project裡面的values, layout等xml定義資源, 都會自動編譯成.R . 但Eclipse的ADK並沒有很好的處理, 在你引用.R時, Eclipse的自動建議會幫你import錯誤的Android.R. 但其實應該是你目前專案的才對, 這時候要自己輸入import my.package.R. my.package填你建立專案時的包裝名稱

Clean Project

也是跟資源相關係問題, 有時候就算你xml定義好, 也正確的import, 還是會有找不到資源的問題, 這時候可以做兩件事. 先檢查你的xml是否有語法問題. 確認都正確後, 利用Eclipse選單的Project>Clean..去重新編譯資源檔

Empty Adapter

當你想清除原本已綁定(inflate)的view物件, 例如spinner, 網路上找到的view.item.clear()跟view.setAdapter(null)都是錯誤的, 我不知道為甚麼他們要這樣寫, android從2.2.3到4.3.1的API都沒有這兩個定義. 後來我的做法是產生一個沒有內容的adapter, 例如沒有字串的字串陣列, 然後setAdapter(empty)

Localization

若你想支援Localization, 最好是從第一行程式開始就把所有字串都利用values裡的strings.xml參考, 不然之後會找字串找得很痛苦. 包括menu裡的字串也要從strings.xml讀取

GetView(row)

Adapter裡的一個方法, google提供的範例沒有說明原來方法的第二個參數其實是view object的cache (convertView), 檢查這個若不是null, 就直接回傳這個, 可以減少重覆inflate, 有較好的performance

Code Version

每一次想要上傳至Google Play都要改, 簡單的處理方法就是+1, 不然會上傳失敗

Export key

上傳Google Play一定要用的key, 產生時記得年期選100年或以上, 不然會上傳失敗. 雖然我不知道100年跟永久有甚麼分別, Google也不見得可以維持100年…

2013 boring life summary

上一次更新已經是2012 sept. 了! 其實我早就放棄這個blog, 但回來看一下原來我有在寫的時候真的有人在看!
沒有寫的原因, 其中一個是, 技術方面我已經比較少在研究了, 生活也一成不變, 所以…

不過偶而寫一篇記錄一下也無傷大雅, 整理一下2013的軌跡
九月, 我拆牙套了
今年開始比較認真的學結他, 買了我的PRS EG, 我還蠻喜歡的
XBOX360我賣了, 剩下遊戲片以及一支大搖!!
還在新竹, 同一家公司, 做著相同的事, very f23king boring.
跟肥貓豆豆生活一段日子了, 有貓貓很不錯
強仔結婚了, 難得聚在一起, 在台北玩, 還去宜蘭沖浪
伍健做了真正的爸爸

開發軟體方面, 少用了資料庫跟網頁, 多做了很多網路, WPF等東西
最近玩了一下coroana sdk, 還不錯, 還有學了一些javascript event的東西, 有空再寫

2014, 我希望不會再浪費時間, 集中精神在自己真正常做的事上面, 還希望可以多陪家人. 我已經浪費太多時間了

Android 開發Part3

前一篇Part2

Part3的內容 – asynchronous task, view inflation, file I/O.

AsyncTask

為了不影響介面反應, 長時間執行事件需要在背景執行, 利用AsyncTask是不錯的方法。

先看一下官方文件, 這裡最重要的就是泛型宣告, 三個泛型分別用在執行, 進度, 完成三個不同的事件處理器. 這裡要先了解一下AsyncTask的生命週期. 在AsyncTask裡啟動後, 首先會執行doInBackground, 這就是背景方法, 長時間事項要在這個handler裡面進行, 系統會安排背景執行緒去處理. 過程中onProgressUpdate會被呼叫, 用來通知UI事件還在處理中, 這個方法可以不實作. 最後在doInBackground完成後, onPostExecute會被呼叫, 這方法通常是用來把結果顯示於介面. onProgressUpdate和onPostExecute都是介面執行緒負責, 所以可以用來更新介面.

有這個了解之後, 就可以回到泛型, 第一個是doInBackground的參數陣列物件的型別, 第二個是onProgressUpdate的, 第三個是doInBackground傳給onPostExecute的運作結果, 所以doInBackground的return type會跟onPostExecute的參數相同.

這就是AsyncTask的主要功能, 接下來看幾段sample code

MainActivity.cs 產生並啟動AsyncTask

MyAsyncTask task = new MyAsyncTask(this);

task.execute(“Hello”, “World”);

MyAsyncTask.cs定義MyAsyncTask

Public class MyAsyncTask extends AsyncTask<String, Void, String>

{

//skip constructor def

@Override

protected String doInBackground(String… params)

{

String hello = params[0];

String world = params[1];

return hello + “ “ + world;

}

@Override

protected void onPostExecute(String result)

{

TextView view = mainActivity.findViewById(R.Id.mytextview);

view.SetText(result);

}

}

這兩段程式, 首先mainActivity會建立並呼叫MyAsyncTask, 在constructor把自己傳給MyAsyncTask, 讓task可以更新介面, 並給兩個字串參數. MyAsyncTask把兩個參數組合並把結果顯示在一個TextView.

資料綁定Inflation

Android把資料綁定稱為inflation, 資料綁定就是把資料利用指定的介面模版, 是應用程式常見的概念. Android把模版看成是氣球, 把資料吹進去成型, 是很貼切的稱呼.下面是一個最精簡的sample

MyActivity.cs

public class MyActivity extends Activity

{

ArrayAdapter<String> adapter = new ArrayAdapter<String> (this, android.R.layout.simple_spinner_item, new String[] {“water”,“coffee”, “tea”});

Spinner s = findViewById(R.Id.spinner1);

s.setAdapter(adapter);

}

這個程式碼會把三個字串送進一個spinner, spinner是類似下拉式選單的元件.

Inflation其實需要三種物件互相配合, View, Data, Adapter, View負責顯示, Data記錄內容, Adapter就是負責把Data轉成View可以使用的介接器. 這個例子使用Android內建的ArrayAdapter介接, 配合R.layout.simple_spinner_item為Spinner的每一個row的模版. 下一次我會介紹如何使用自訂layout和自建Adaptor.

File I/O

Android有很多種資料儲存方式, 例如SQLite和Preference, 這裡先介紹File I/O.

寫入檔案

FileOutputStream fs = myActivity.openFileOutput(filename, Content.MODE_PRIVATE);

OutputStreamWriter fwrite = new OutputStreamWriter(fs);

fwrite.write(“hello world”);

fs.close();

利用openFileOutput新增一個名為filename的檔案, 並且把Access Control設定為PRIVATE, 內建還有好幾種Access權限, 按需求而選. 寫入字串後關閉.

讀取檔案, 基本上跟寫入相反就可以

InputStream fs = openFileInput(filename);

InputStreamReader fread = new InputStreamReader(fs);

BufferedReader freadBuffered = new BufferedReader(fread);

StringBuffer bffr = new StringBuffer();

String temp = null;

while((temp = freadBuffered.readLine()) != null)

{ bffr.append(temp+”\n”); }

fs.close();

Part 4會介紹如何把Part1~3的功能合起來使用, 例如使用Listener管理AsyncTask的結果, Inflate自訂Layout等

Release Mode程式, 利用Ildasm除錯

如果.NET程式遇到圖一這種情況, 可以利用事件檢視器和Ildasm工具找出問題的原因.

首先, 打開 控制台>…>事件檢視器, 路徑會因為作業系統而改變, Win7是控制台>系統及安全性>檢視事件記錄檔

找出錯誤記錄, 圖二, 記錄描述解讀如下

P1 出錯的程式名稱, P4 出錯的組件, P7 組件裡出錯的方法, P9 錯誤名稱

根據圖二, 出錯的是system.windows.forms, 錯誤為argumentnullexception

接下來就要找出是那一個方法出錯, 先打開Ildasm反組譯工具, 可能找看看下列位置

% WindowsRoot%\Microsoft.NET\Framework\version\

%Program Files%\Microsoft SDKs\Windows\version\bin

我是在%Program Files%\Microsoft SDKs\Windows\v7.0A\bin 找到的

執行Ildasm, File>Open, 把P4的組件打開, 打開後點選View>MetaInfo>Show!

會打開一個文字檔, 裡面是該組件的meta資料, 利用Find功能找出有問題的方法

搜尋 0600+P7, 根據圖二, 這裡要搜尋的是06001521, 找到一個名稱Method #467 (06001521) NotifyEnter的方法

也就是說, 程式裡導致錯誤的原因跟system.windows.forms NotifyEnter方法相關

P.S. Report to Microsoft一點用都沒有, 還是靠自己吧

Android 開發Part2

介面設計

Package Explorer裡, 在Android專案的res資料夾, right click->New->Android XML file. 選一種Layout (最基本的是LinearLayout), 點Next

點Next之後, 會出現一個設定Qualifers的介面, 這裡要小心, 如果你不知道甚麼是Qualifers, 就先不要設定, 不然啟動Activity時會有ResourcesNotFound Exception. 那是因為你有加Qualifers限制, 而AndroidManifest.xml的設定沒匹配, 就會找不到Resources, 也就是你的layout.xml會找不到.

Android介面物件的大小, 單位是dp, 例如一個ImageView的Height = 100dp. 錯了單位compiler不會過. Padding和Margin的單位是dip, 例如marginBottom=”10dip”.

要對齊元件, 要使用Container(或Layout)的Gravity屬性

如果發現Graphical顯示的結果, 長寬怪怪的, 或者orientation不對,  請在畫面設計工具上方設定target device, orientation和主題

啟動Main Activity

跟整個程式有關的設定, 都在AndroidManifest.xml.

先設定本程式會用到的資源uses-permission, 例如android.permission.INTERNET就是需要上網

AndroidManifest.xml裡應該有註明本程式所有的Activity, 一個程式裡的每一個頁面都是獨立的Activity. 要指定一個Activity作為初始, 在<activity/>裡加入<intent-filter/>, filter裡有放兩個elements, 分別是<action android:name=”android.intent.action.MAIN” />和<category android:name=”android.intent.categroy.LAUNCHER”/>

資源管理

layout的xml, drawable如圖片檔, values的xml, 都是放在res裡的資源.

加入圖片檔, 使用一般的複製貼上就可以, 但android對不同resolution的畫面可以使用不同的圖, 分別存放在後綴hdpi, ldpi, mdpi, xhdpi.

顏色定義, 命名好像規定要用Color當後綴, value可以是#RRGGBB或#AARRGGBB

利用資源id除錯. 寫以下try, catch

try

{  //do things with resources }

catch(Exception e)

{

Log.e(“ERROR”, e.toString());

}

Log會告訴你出錯的resource ID, 進去gen>package.yours>R.java 裡面有寫

內部Intent

利用內部Intent在程式內切換頁面

主動的Activity

Intent turnPageIntent = new Intent(view.getContext(), NextActivity.class);

startActivityForResult(turnPageIntent, 0);

這樣就會叫起下一個Activity

被呼叫的Activity

Intent returnIntent = new Intent();

setResult(RESULT_OK, returnIntent);

finish();

這樣就會回到前一個Activity

一定要用到的Event

在Activity裡

@Override

Public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.yourLayout);

}

按鍵事件

Button theButton = (Button)findViewById(R.id.buttonId);

theButton.setOnClickListener(//your code);

如何把ASP.NET網頁部署至AZURE

Azure簡介

微軟的雲端作業系統。登入https://manage.windowsazure.com/或進到Azure官網點右上角的Portal。

目前Azure支援的有Web Sites, Cloud Services, SQL Databases, Storage。

Web Sites : 靜態網頁。只態使用IIS。

Cloud Services : 動態內容。即Web Application, Web Service等。

SQL Database : 資料庫。

Storage : 類似Google Big Table,好像還可以儲存檔案。

ASP.NET web application

會用到SQL Database和Cloud Service。

SQL DATABASES

首先建立一個Database,Collation目前使用SQL_Latin1_General_CP1_CI_AS。透過SQL的[N””]可儲存中文,例如INSERT INTO table (column) VALUES (N’中文內容’)。其他參數跟付費內容有關。

建立後系統會產生一個domain,例如我們在東亞的abc1234def.database.windows.net,這個可以用ssms登入管理。頁面上有一個[Show connection strings]可以顯示連結字串,預設限定tcp,不能使用namepipe,而且有firewall,要在firewall加入允許規則才可以連線。防火牆設定在SQL Databases->Servers Tab->選一個instance->Configure

SQL schema請使用Sql Migration Wizard從Local Database上傳至Azure Sql Database

CLOUD SERVICES

先建立一個instance,quick create就可以,有兩種模式,production和staging,測試中就選用staging。接下來要先把Web Application打包,deploy後才能再作後續設定。

VS2010

下載並安裝Azure SDK。在原本的Solution底下新增一個Azure Project,不要選擇任何web role->完成。[以下稱Azure Project]

產生空白專案後,在Solution Explorer->Roles上按右鍵,選Web Role in solution,把你想deploy到Azure的web application project加進去[以下稱WebApp]。在WebApp加入Microsoft.WindowsAzure.ServiceRuntime這個參考。

接下來要調整web.config。可以透過在Azure Project按右鍵->屬性設定,也可以在cscfg和csdef這兩個xml手動設定。Csdef會定義cdcfg裡有甚麼設定值(session),實際運行用的參數值會在cscfg。大概只會用到connectinstring。Connectionstring請參考在SQL DATABASE一節的取得方法。

修改Source Code

Azure不支援ConfigurationManager物件,請把所有跟ConfigurationManager相關的程式碼修改成如下(以connectionstring為例):

if (RoleEnvironment.IsAvailable)

{

param = RoleEnvironment.GetConfigurationSettingValue(“key”);

}

else

{

param = ConfigurationManager.ConnectionStrings[“key”].ConnectionString;

}

封裝Azure Project

在azure project按右鍵,選封裝,系統就會把專案包裝成兩個檔案,準備好上傳至Azure Cloud Service。這時候請注意VS2010的輸出,如出現WAT##等警告,請執行對應的處理。

X64平台

Cloud Service是X64平台,所以你的WebApp及所有參考的dll都需要編譯成x64使用。

服務部署

在Azure Portal選Cloud Services,選一個instance,再選Deploy,輸入Deployment Name,package是封裝時產生的.cspkg檔,configuration是.cscfg檔。完成後請選Link Resources頁面,新增SQL Database一節時所建立的 Instance。到這裡基本上已完成WebApp的部署

Appendix

Membership

如果你的程式有使用Asp.Net Memebership,請使用以下script在SQL Database的管理介面執行,這些script會建立所需要的tables, views, store procedures。

注意,必需先執行InstallCommon.sql。

網頁亂碼

請檢查WebApp的source code,需使用UTF-8儲存,檢查及修改在VS2010->檔案->進階儲存選項…

Setup Eclipse with Subversive, Upload to CodePlex

首先安裝Eclipse, 然後到Help->Install New Software…

然後加入Helios的路徑, http://download.eclipse.org/releases/helios

讀取列表成功後, 選Collaboration->Subversive SVN Team Provider->Next

安裝完畢後重新啟動Eclipse.

重啟後選Window->Preferences->Team->SVN, 它會叫你安裝connector.

如果是Windows系統, 可以安裝Native JavaHL版的connector. 安裝好後重開

最後在Package Explorer用右鍵選你要上傳到SVN的專案, 選Team->Share Project

SVN->Next, URL輸入你在CodePlex看到的那一條, 就大功告成

iOS Apps 開發環境架設 for Poor People!

嘗一下iOS apps開發要多少錢?? 大概1000元! (謎:甚至0元)

首先, 這都要多謝Larry, Virtualbox開始支持 Mac OS

要準備幾樣東西, Virtualbox, 20~40GB空間, 一片Mac OS安裝光碟

不過免錢的東西沒那麼簡單, 要先講一些背景知識

Mac OS原本並不支援Intel跟AMD的CPU, 好像是在10.5開始才出現Intel架構

而且Mac OS並不是用BIOS的, 是用一種更先進的東西叫EFI

所以我用的是Mac OS X Snow Leopard 10.6 Intel版, 還有一個EFI loader

沒有這些東西的話, 請向Apple購買, 或者找Empire, 就這樣, 不多講了

安裝好Virtualbox後, 建立一台Mac OS機器, 硬碟空間調越大越好, 因為這個之後是無法改變的

建議至少40G, 因為全部東西安裝好之後, 好像有20幾GB.

在啟動該機器前先做以下設定 : uncheck EFI模擬, 放入光碟並設定成開機設備, 啟動

接著順利的話就會看到安裝畫面, 沒有甚麼特別, 就安裝吧

安裝好之後, 就會看到那個紫色的畫面. 去下載Xcode, 註冊成Apple Developer是不用錢的

整套IDE含SDK及Emulator大概3.52GB, 安裝後8GB

有一件很重要的事, 千萬別對系統做任何更新, 然後裝好系統需要重開

關機之後, 如果要進入系統, 這時候要check EFI模擬

IDE本身沒甚麼好講的, 因為全部是Apple Bundle好的, 沒甚麼特別要設定

去Finder->Developer->Tool->Xcode啟動, Finder類似Windows的Explorer

如果你去過Empire, 就去裡面找一個叫Post-Install的資料夾, 執行裡面的myHack

要修改Resolution的話, 去/Library/Preferences/SystemConfiguration找com.apple.boot.plist

加入key為Graphics Mode, string為你想要的resolution例如1280x1024x32

總結, 你可以run emulation, 但要deploy到device就要交錢,

而且要自己準備device, 應該還要Mac的設備

不過在決定要不要花這一大筆錢前先感受一下是好的,

因為好像要寫Objective-C, 聽說不怎麼簡單