2011年5月10日 星期二

Android Application Components

Android 應用程式 構成要素

具有以下四種要素:
  • Activities (活動,前景執行的程序)
    • 一個Activity代表一個單一的螢幕與一個使用者介面。

    • 例如,一個email Application也許它有一個Activity用來顯示一個新的電子郵件列表(new email list),另一個Activity撰寫電子郵件,而另一個Activity則是讀取郵件,這些Activity work凝聚在一起形成了一個電子郵件應用程式,但其實每一個Activity都是獨立的,因此不同的Application可以啟動任一個Activities(如果電子郵件應用程序允許的話)。

    • 例如,攝影機的Application可以啟動email Application的new email的Activities,撰寫新的郵件,讓使用者可以分享圖片。

    • android中的任何activity都是Activity的子類,應用程式中屬於Activity的程序都需要extends Activity這個類或其子類,關於更多的Activities學習請參考Activities學習指南
  • Service(服務,背景執行的程序)
    • Service是一個Component,運作於背景,用來執行長時間運行的操作或是遠端操作的處理程序(remote process)。

    • service是不提供使用者操作介面的(在背景當然不需要囉)。

    • 例如:一個service在背景程序中執行音樂播放,而使用者在其他的Application中執行操作,也可能利用一個remote service經由網路取得資料而不干擾使用者正在進行互動的activity。

    • 其他的component,如一個activity,可以啟動service讓他運作或是綁定(bind)他,目的是為了讓他可以互動。


    • andorid中的service都是Service的子類,屬於service的程序都需要繼承Service或其子類,關於Service請參考Service開發指南
  • Content providers (內容提供者)
    • 一個Content providers管理一組共享的application資料。

    • 你能夠在檔案系統中儲存資料,一個SQLite資料庫在web上或其他持久性的的儲存位置,你的application可以存取。

    • 透由Content providers,其他的應用程式能夠查詢或是修改資料,如果內容供應者允許的話(if the content provider allows it)。

    • 例如,Android系統提供一個Content provider管理著用戶的內容資訊(contact information)。因此任何具有適當權限的應用程序可以查詢部分content providers(ContactsContract.Data)的讀取與寫入特定人的相關訊息。

    • content providers也用於私有的(private)讀取與寫入,在你的應用程式上並且不是分享的。例如,Note Pad應用程式使用一個content provider保存筆記。

    • Android中的content provider都是ContentProvider的子類,content provider除了實現了ContentProvider之外還需實現一套標準的API,使得其他程序能夠藉由API來交易取得資料,關於ContentProvider請參考ContentProvider開發指南

  • Broadcast receivers (廣播接收機)
    • 一個Brodcast receivers是一個component,他用來回應系統全部的廣播通知。

    • 許多廣播是源自於系統本身,例如,螢幕被關閉、電量不足、圖片被截取。

    • 應用程序也可以發出廣播訊息,例如,令其他的應用程式知道,有一些資料已經被下載到裝置上,是可以被使用的。

    • 雖然broadcast receivers不會顯示一個使用者介面,但他們可能會建立一個status bar notification (create a status bar notification)來提醒用戶一個廣播事件發生。

    • 更常見的是, though, a broadcast receiver is just a "gateway" to other components and is intended to do a very minimal amount of work.(做一個非常少量的工作)

    • For instance, it might initiate a service to perform some work based on the event.
      例如它可能會啟動一個service來執行一些基礎的工作。

    • Android的broadcase receiver都是BroadcastReceiver的子類,且每一個broadcast都會交付一個Intent物件,更多的訊息請看BroadcastReceiver Class。

Android Application Fundamentals

Android 應用基礎


Android的應用程式是使用Java程式語法撰寫的,程式的原始碼經由Android的SDK tools編譯成.apk檔,這個.apk檔案可以讓Android行動裝置安裝應用程式使用。

一但將應用程式安裝在行動裝置上,每一個Android的應用程式是存活在他自己的security sandbox裡。
  • Android的操作系統(指OS),是多使用者的Linux系統,每一個應用程式在Linux中都是不同的使用者。
  • 預設,每個應用程式在Linux中會有一個唯一的使用者ID,Linux會設定好檔案權限,讓應用程式只能操作屬於自己權限的檔案。
  • 每個程序都有他自己的虛擬機器(virtual machine , VM),應此每個應用程序運行是彼此隔離的。
  • 預設,每一個應用程式執行在自己的Linux process上。Android starts the process when any of the application's components need to be executed, then shuts down the process when it's no longer needed or when the system must recover memory for other applications
然而有一些方法可以讓兩個應用程式共享資源:
  • 可以安排兩個應用程序分享共同的Linux user ID,這樣他們就可以共用檔案文件,為了節省系統資源,也可將有共同用戶ID的應用程序安排運作在相同的Linux process,共享一個VM(應用程序必需簽署相同證書)。
關於Linux process請查閱計算機結構或作業系統書籍解釋。
  • 應用程式可以請求對於裝置設備、資料的存取權限,如用戶的聯繫人(user's contacts)、簡訊(SMS messages)、SD card、攝影機(camera)、藍芽(Bluetooth)、等等,所有的應用程式權限申請,發生在使用者安裝時期。

關於Android開發環境安裝請參考:
Android Linux上開發環境安裝

參考文件:
內容來自於Android官方開發指南文件,詳細內容請見

2011年5月7日 星期六

Flex4 Application(一):SystemManager、SystemManager.application、 topLevelApplication之間關係

Flex 4中的一個變更:
Flex3中Application裡的屬性application這個屬性在Flex4中被拿掉了,改由 FlexGlobalse這各類管理,由FlexGlobalse的topLevelApplication屬性代替原本的appliction,topLevelApplication這是一個靜態的屬性。

什麼是topLevelApplication?
的ApplicationDomain中運行的第一個應用程序是頂層應用程序在頂層應用程序的構造函數中將此屬性設置為對頂層應用程序的引用每個 ApplicationDomain中都有其自己的topLevelApplication,這個topLevelApplication通常就是一支SWF,在Flex中這支SWF通常會是一個Application的實體,在一個ApplicationDomain中可能會有多個SWF存在,但只會有一個負責管理所有應用程式的最上層Application,這個管理者就是topLevelApplication。


adobe技術手冊中的圖示如下:

















範例:在一SWF中利用Loader讀取另一支SWF,在loader()第二個參數使用預設null。
請參考LoaderI與LoaderContext
  • loader()第二參數為null時,將使用Loader所在的Application的ApplicationDomain。
程式碼Hero_Test.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  xmlns:s="library://ns.adobe.com/flex/spark"
  xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="1280" minHeight="780"
  applicationComplete="application1_applicationCompleteHandler(event)"
  pageTitle="Hero_Test"
  >
<fx:Script>
<![CDATA[
import mx.core.FlexGlobals;
import mx.core.UIComponent;
import mx.events.FlexEvent;
import mx.managers.SystemManager;

 private var _loader:Loader;
 private var _request:URLRequest;
 private var _systemManager:SystemManager;
 protected function application1_applicationCompleteHandler(event:FlexEvent):void
{
 initLoader();
 deployLoader();
 startLoader();
 btn.addEventListener(MouseEvent.MOUSE_DOWN , onDown);
}
 private function initLoader():void
{
  _loader = new Loader();
  _loader.contentLoaderInfo.addEventListener(Event.COMPLETE , onLoaderComplete);
  _request = new URLRequest('./swf/ByLoaderSWF.swf');
}
private function deployLoader():void
{
  uic.addChild(_loader);
  this.box.addElement(uic);
}
private function startLoader():void
{
  _loader.load(_request);
}
private function onLoaderComplete(e:Event):void
{
 _systemManager = _loader.content as SystemManager;
 changedColorBtn.addEventListener(MouseEvent.MOUSE_DOWN , onChangeColor);
  uic.width = _loader.content.width;
  uic.height= _loader.content.height;
}

private function onChangeColor(e:MouseEvent):void
{
 var color:uint = Math.round(Math.random()* 0xFFFFFF);
  _systemManager.application['setByLoaderSWFbackgroud'](color);
  info.text = color.toString();
}

private function onDown(e:MouseEvent):void
{
 var o:Object = FlexGlobals.topLevelApplication;
 info.text ="";
 info.text = "this = " + this + '\n\n';
  info.text += 'topLevelApplication = ' + o.toString()+'\n\n';
  info.text += 'systemManager = ' + this.systemManager + '\n\n';
}

]]>
</fx:Script>
<s:HGroup id="box">
<s:VGroup>
<s:Panel title="Hero_Test">
<s:TextArea id="info" editable="false" width="420"/>
</s:Panel>
<s:Label text="print Hero_Test資訊"/>
<s:Button id="btn" label="print"/>
<s:Button id="changedColorBtn" label="changeColor"/>
</s:VGroup>
<mx:UIComponent id="uic"/>
</s:HGroup>
</s:Application>


程式碼ByLoaderSWF.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  xmlns:s="library://ns.adobe.com/flex/spark"
  xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="600" minHeight="200"
  applicationComplete="application1_applicationCompleteHandler(event)"
  pageTitle="ByLoaderSWF"
  backgroundColor="0xA1FF8F"
  >
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.controls.ProgressBar;
import mx.core.FlexGlobals;
import mx.events.FlexEvent;
import mx.managers.SystemManager;
import mx.preloaders.DownloadProgressBar;

protected function application1_applicationCompleteHandler(event:FlexEvent):void
{
 Security.allowDomain("*");
 btn.addEventListener(MouseEvent.MOUSE_DOWN , onDown);
}
private function onDown(e:MouseEvent):void
{
 var _topLevelApplication:Object = FlexGlobals.topLevelApplication;
 info.text ="";
 info.text = "this = " + this + '\n\n';
 info.text += 'topLevelApplication = ' + _topLevelApplication.toString()+'\n\n';
 info.text += 'systemManager = ' + this.systemManager + '\n\n';
}

public function setByLoaderSWFbackgroud(color:uint):void
{
  this.setStyle("backgroundColor",color);
}

]]>
</fx:Script>
<s:VGroup>
<s:Panel title="ByLoaderSWF資訊看板">
<s:TextArea id="info" editable="false" width="450"/>
</s:Panel>
<s:VGroup>
<s:Label text="Print ByLoaderSWF資訊"/>
<s:Button id="btn" label="print"/>
</s:VGroup>
</s:VGroup>
</s:Application>


將這兩支mxml編譯成SWF,並將發佈的的資料放置Web Server中運行。

  • 注意,Loader在load SWF時,無法在flashBuilder中直接執行運作,因為Loader SWF不可在本機上執行,這是FlashPlayer的安全機制,將其放置Web Server中運行即可。










我們可以看到ByLoaderSWFtopLevelApplication是指向Hero_Test。



而我們可以在Hero_Test中呼叫ByLoaderSWF的public function 。

呼叫ByLoaderSWF的setByLoaderSWFbackgroud(color:uint)方式如下:

//在Loder的contentLoaderInfo讀取完畢發出Complete時將Loader的content轉成SystemManager。
private var _systemManager:SystemManager;

private function onLoaderComplete(e:Event):void
{
_systemManager = _loader.content as SystemManager;
changedColorBtn.addEventListener(MouseEvent.MOUSE_DOWN , onChangeColor);
}
//在Button被按下後呼叫,利用_systemManager來呼叫setByLoaderSWFbackgroud(color:uint)


private function onChangeColor(e:MouseEvent):void
{
var color:uint = Math.round(Math.random()* 0xFFFFFF);
_systemManager.application['setByLoaderSWFbackgroud'](color);
info.text = color.toString();
}


什麼是SystemManager?

  • SystemManager是應用程式的根(root)。
  • SystemManager是MovieClip的子類,有兩個影格。
  • SystemManager在第一個影格是預載器,在此會載入。
  • SystemManager在第二個影格會開始建立主要應用程式的實體。
  • SystemManager有個application屬性,會指向Application的實體。
  • application這個屬性在第二影格建立屬性前都會是null,也就是說SystemManager是一支應用程式中最先建立的然後才是建立Flex中主要應用程式的類別(如Application)。

systemManager中有一個屬性application其實就是Application的instance,而在這裡_systemManager中其實就是ByLoaderSWF的SystemManager。

關於this對象、SystemManager對象、SystemManager.application在ByLoaderSWF單獨執行下的追蹤結果。

2011年5月1日 星期日

BitmapData應用: Text轉換

BitmapData應用,Text或是任何DisplayObject皆可轉換

BitmapData and Text - wonderfl build flash online


點擊click me之後會將text欄中的文字轉換。
要點在於,將displayObject元件轉成BitmapData,然後再解析bitmapData資料的每一點像素,再用繪圖一個圓或其他圖形來代替像素位置。

繪圖API + GlowFilter + BitmapData運用

繪圖API + GlowFilter + BitmapData運用

Circle and GlowFilter - wonderfl build flash online

BitmapData pixelDissolve使用



點擊連結可以直接看程式碼,這個日本的網站很好,你可以把程式碼輸入他會幫你編譯成SWF,並且提供HTML的Embed code可以讓你把swf貼在blog,像我這種沒有空間可用的人覺得好方便。

這個例子你只要用loader取回圖片,將loader轉成bitmapData就可以使用兩張圖片互換

//用這取得BitmapData
public function cloneBitmapData(loader:Loader):BitmapData
{
 var bd:BitmapData = new BitmapData(loader.content.width , loader.height);
 bd.draw(loader.content);
 return bd;
}

這個應用要注意的是,pixelDissolve()執行完會傳回一個新的seed,記得把這seed存下來,下次會用到。

2011年4月27日 星期三

Bitmap 粒子(一)

package
{
 import flash.display.Bitmap;
 import flash.display.BitmapData;
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.filters.BitmapFilterQuality;
 import flash.filters.BlurFilter;
 import flash.geom.Point;
 [SWF(width="1024", height="768", frameRate="30", backgroundColor="#000000", pageTitle="粒子測試")]
 public class particale extends Sprite
 {
  private var _bitmapData:BitmapData;
  private var _photosphereMap:Bitmap;
  private var _sprite:Sprite = new Sprite();   
  //活動場景大小
  private var _mapWidth:Number = 400;
  private var _mapHeight:Number = 400;
  //顆粒大小
  private var _particaleSize:Number = 10;  
  //位置與量
  private var _position:Point;
  private var _vector:Point;
  //濾鏡強度
  private var blurX:Number = 1.5;
  private var blurY:Number = 1.5;

  public function particale()
  {
   super();
   init();
  }
  private function init():void
  {
   initPhotosphereMap();
   deployPhotosphere();
   initPostiton();
   initVector();
   onStart();
  }