2012年6月30日 星期六

[Spring] Spring Expression Language (SpEL)

Assume get this value from DB #{#root["valueB"]}/path
// Using Expression parser, valueB should be found from DB, too.
Expression expression = parser.parseExpression(property.getValue(), 
    new TemplateParserContext());
property.setValue(expression.getValue(context, String.class));


* Reference
- Spring Expression Language (SpEL)

2012年6月22日 星期五

[Web] Brief notes


  • slf4j
    • 在 jar 檔時就 binding,比較好切換。
  • framework
    • 提供 pattern 的模組
  • Spring framework
    • 本身是個大 factory,將工作交給底下的 factory...
  • Struts2
    • #attribute 作用約是 ${attribute}
  • iBatis
    • $var$
      • paraClass 中的 attribute
    • #fieldName:fieldType#
      • Table field
  • HTML
    • 由上而下 compiler,結果會是 DOM tree 結構。
    • DTD
      • 描述 HTML syntax
    • <meta>
      • 提供和 browser or search engine 相關的訊息。
      • ex: 描述文檔的內容。

2012年6月15日 星期五

[Android] Context

public abstract class Context
  • 管理 global application 資訊的 interface,是由 Android System 實作。
    • Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system.
  • 可由此取得 application-specific 的 resources and classes。
    • It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.

getApplicationContext()
  • 在啟動 app 時,預設會啟動 Application,也就是 AndroidManifest.xml 中的 <application>,因此也能自己實作指定在此 tag 中,替代此預設。
  • 回傳所在 process 中的 global application context。
    • Return the context of the single, global Application object of the current process.
  • 應被使用在當 lifecycle 不和當前 component 綁在一起時。
    • This generally should only be used if you need a Context whose lifecycle is separate from the current context, that is tied to the lifetime of the process rather than the current component.
ex: 
  • registerReceiver(BroadcastReceiver, IntentFilter)
    • 如果使用的是 Activity context,這個 receiver 就是被註冊在此 Activity,所以你必須在此 Activity destroy 前 unregister 此 receiver,若沒有這樣做則會發生 exception。
      • If you use the Activity context to register a receiver that is static (global to the process, not associated with an Activity instance) then that registration will be removed on you at whatever point the activity you used is destroyed.
    • 如果是使用 Application context,這個 receiver 是和 application 相關連,因此不會被 unregistered,但有可能會造成 leak。
      • However using the ApplicationContext elsewhere can easily lead to serious leaks if you forget to unregister, unbind, etc.
  • 使用在 DB 操作時。


* Reference
- 求getApplicationContext用法-Android 问题&解答-eoeAndroid开发者社区 - Powered by Discuz!
谈谈Android里的Context的使用!!! - Android_Tutor的专栏 - 博客频道 - CSDN.NET

[JPA] @OneToMany

// ObjectA many-to-one with ObjectB

// In ObjectA
// mappedBy  的值是在 ObjectB 中的 attribute
@OneToMany(fetch = FetchType.LAZY, mappedBy = "objectA")
public List<ObjectB> getObjectB()  {  
    return objectBs;  
}

// In ObjectB
@ManyToOne(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinColumns({
    @JoinColumn(name = "FIELD_X", referencedColumnName = "FIELD_X", insertable = false, updatable = false )
})
public ObjectA getObjectA() {  return objectA; }

[Database] BigDecimal

當 table 對應為物件時

若其 value 長度可能會超過 java int

這時候就會使用 BigDecimal type

ex: 流水號


* Reference
- How big is BigDecimal?

[Graphic] Gif format

GIF 的版本有分
  • GIF 87a: 不會動的
  • GIF 89a: 此版本的格式才支援動態


不會動的一定是 87a 格式

或是可以使用 Ultra Edit 查看 header

可分辨是何種格式的


* Reference
- wiki GIF

[AndroidLayout] Inflate layout

Error Message
06-11 16:31:59.046: E/ListView(28360): at java.lang.reflect.Method.invoke(Method.java:507)
06-11 16:31:59.046: E/ListView(28360): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
06-11 16:31:59.046: E/ListView(28360): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
06-11 16:31:59.046: E/ListView(28360): at dalvik.system.NativeStart.main(Native Method)


Solution

inflate layout 傳入參數為

inflate(R.layout.items_row, parent, false);

or

inflate(R.layout.items_row, null);



* Reference
- Android: Custom ListAdapter extending BaseAdapter crashes on application launch

2012年6月9日 星期六

[Android] Content Provider

  • Content providers are the standard interface that connects data in one process with code running in another process.
  • The provider and provider client automatically handle security and inter-process communication.

ContentResolver
  • In the client application's process.
  • Owns the provider automatically handle inter-process communication.
  • Acts as an abstraction layer between its repository of data and the external appearance of data as tables.

query(Uri, projection, selection, selectionArgs, sortOrder)
Should do queries asynchronously on a separate thread. (ex: CursorLoader class)
  • projection: the columns that will be returned for each row
  • The expression that specifies the rows to retrieve is split into a selection clause and selection arguments.
  • selection
    • The selection clause is a combination of logical and Boolean expressions, column names, and values (the variablemSelection).
    • selection 中的值應用 ? 取代,實際的值放在 selectionArgs(the selection arguments array ),作為對應.
    • The selection clause is set to null, and the query returns all the words in the provider

Query result:
  • If no rows match the selection criteria
    • Cursor.getCount() is 0 (an empty cursor).
  • If an internal error occurs
    • Return null, or it may throw an Exception.
  • Since a Cursor is a "list" of rows, a good way to display the contents of a Cursor is to link it to a ListView via a SimpleCursorAdapter.

Content providers can offer the following formats:
You can see the available data types by looking at the Cursor class "get" methods.
  • integer
  • long integer (long)
  • floating point
  • long floating point (double)
  • Binary Large OBject (BLOB) implemented as a 64KB byte array

Three alternative forms of provider access are important in application development:
  • Batch access
    • You can create a batch of access calls with methods in the ContentProviderOperation class, and then apply them with ContentResolver.applyBatch().
    • Useful for
      • Inserting a large number of rows.
      • Inserting rows in multiple tables in the same method call
      • Performing a set of operations across process boundaries as a transaction (an atomic operation).
  • Asynchronous queries
    • You should do queries in a separate thread
    • One way to do this is to use a CursorLoader object. The examples in the Loaders guide demonstrate how to do this.
  • Data access via intents: 
    • Although you can't send an intent directly to a provider, you can send an intent to the provider's application, which is usually the best-equipped to modify the provider's data.


* Reference
- Content Providers
- Content Provider Basics

[Android] Links in TextView

* Reference
- public class LinkMovementMethod
- public class Linkify
- Android: Clickable hyperlinks in AlertDialog
- How do I make links in a TextView clickable? ***
- TextView 加链接所有方法 **

2012年6月3日 星期日

[Database] DataSource

有下列管理 transaction 的方式:
  • JDBC
  • JTA
    • 管理的範圍較廣,可以包含多種不同來源。
  • DataSource

連至 DB 的方式:
  • Local -> server -> DB
    • 要透過 jndi 向 server 取得 look up service -> DATASOURCE。
    • Too dependent on server.
  • Local -> DB
    • Security issue(user, password).

If web service is on Server:
  • 可以直接對應 jndi 取得 Datasource。


If NOT:
  • 方式一: 利用 InitialContext預設會使用 jndi.properties 中的 jndi name。
public class DataSourceFactory {

    private static DataSource dataSource;

    public static synchronized DataSource getDataSource()
            throws ConnectionException, NamingException {
        if (dataSource != null) {
            return dataSource;
        }

        String datasourceJndiName = Configuration.getInstance().getJndiName();
        if (datasourceJndiName == null) {
            throw new ConnectionException("cann't find datasource jndi name!");
        }
        InitialContext ctx = new InitialContext();
        DataSource ds = (DataSource) ctx.lookup("java:comp/env/" + datasourceJndiName);
        dataSource = ds;
        return dataSource;
    }
}
  • 方式二: springframework configuration, 透過 org.springframework.jndi.JndiObjectFactoryBean。
    • 此設定是 spring 包裝 方式一 取得 datasource 的過程。
    • 在這裡可以自行指定 jndi 變數來源。
    • 若是沒有此設定,則如 方式一 預設使用 jndi.properties 中的設定,因此若沒有在此檔中提供此資訊會掛掉。

[Android] WebView WebViewClient

  • WebViewClient.onLoadResource
    • Anything loaded in webview will pass by.
  • WebViewClient.shouldOverrideUrlLoading
    • Actions occured in webview will pass by.
    • But! Standard links and server redirects trigger shouldOverrideUrlLoading(); window.location does not.

2012年6月2日 星期六

[AndroidProcess] Background works

Main thread 負責處理 UI event,所以也稱為 UI thread,Activity、Service、Receiver、Provider,都是由 main thread 負責執行。因此不能在此 thread 中執行耗時的動作,android 會發出 ANR,這時候就得在 background thread 中執行,讓 main thread 同時仍能回應或執行 UI event,以避免 ANR 狀況。

sendBroadcast() 與 startService() 都一樣會被丟到 main message queue 裡,等待 main thread 的執行,只有呼叫 local content provider 不會進到 main message queue 裡,而是由 main thread 直接執行。但如果是 remote content provider 則是由 thread pool 中取得 thread 來執行,外部 client 呼叫 service 也是如此。

每個 Thread 中都有 Looper 和 Message Queue,Message Queue 中儲存著要被處理的 events (UI event and System event),Looper 負責 Thread 和 Message Queue 間的連繫。

另外,因為是 main thread 負責更新 UI,所以若是試圖在 worker thread 中更新 UI,是會得到 exception 的,必須把更新 UI 的動作再丟給 main thread 處理。


可選擇以下方式:

* Simple Worker Thread and runOnUiThread()/View.post()
View.post()
Each View object has a message queue which is processed sequentially on the UI thread. post() allows us to add a new message to the message queue.
new Thread(new Runnable() {
    @Override
    public void run() {
        // TODO works here.
        
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // UI event
            }
        });

        // or
        final TextView textView =
            (TextView) findViewById( R.id.textview );
        textView.post(new Runnable() {
            @Override
            public void run() {
                // UI event
                textView.setText( "Hello World" );
            }
        });
    }
}).start();

* new Thread + Handler
Handler: 負責處理 thread 的訊息(message)。
private Handler handler = new Handler() {
    @Override
    public void handleMessage(android.os.Message msg) {
        // UI event
        progressDialog.dismiss();
    };
}

new Thread() {new Runnable() {
    @Override
    public void run() {
        // TODO works here.

        // 把 message 送給 handler 處理。
        handler.sendEmptyMessage(0);

        // or 將 Runnable post 到 handler。
        handler.post(new Runnable() {
            @Override
            public void run() {
                textView.setText( "Hello World" );
            }
        });
    }
}.start();

* AsyncTask
  • 如果只會 Override doInBackground 則可考慮使用 Thread 即可。
  • AsyncTask 會 hold Activity context 直到工作結束,所以可能會有 context leak 問題。
new AsyncTask() {
    // onPreExecute(), onProgressUpdate()

    @Override
    protected Void doInBackground(Void... params) {
        // TODO works here.
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        // UI event
    };
}.execute();


** AsyncTask and Handler
  • AsyncTask 內部實做機制為較新且較強的 java.util.concurrent,但較佔資源,而 Handler Thread 則為基本的 Java Thread。
  • 由於 Handler Thread 依靠 Message Queue 與 Main Thread 互動,相對於 AsyncTask,Handler Thread 比較可能發生塞車情況。
  • 但 Handler Thread 在即時互動上優於 AsyncTask,因為 Main Thread 可以隨時傳送 Message 給 Handler Thread,而 AsyncTask 不行,只能依照事先定義 Callback 進行。
  • 基於輕量環境資源的有限,當執行單一的工作時建議使用 AsyncTask,如下載一個大檔案,但是當執行大量重複性的工作時,建議使用 Handler Thread,如下載多個小圖。

* Loader
  • Introduced in Android 3.0 and also included in the Support Library.
  • Used to asynchronously load data in an activity or fragment.
  • Quite effectively to perform these tasks:
    • Loading content either from a SQLite database or file storage, or from a network resource as a background task.
  • There are essentially three components that we need:
  • How to use:
    • Obtain LoaderManager instance from Activity/Fragment/FragmentActivity.
    • Implement LoaderManager.LoaderCallbacks.
      • Will create a loader.
      • Get called when the loader either finishes, or is reset.
      • These will all be executed on the UI thread, and we will typically implement them within our Activity / FragmentActivity.
      • 也就是在 Loader 中處理 UI event。(?)

* Service
  • Services is a means of performing some task which is not attached to a specific Activity.
  • Run in the main thread of their hosting process. (並不會在另一個 thread 中執行,所以不適做耗費 CPU 的工作 會有 ANR 的可能,或者是必須 new a thread。)
  • There are two types of Service:
    • A background Service
      • The default type of Service and can be killed by the OS (or Task Killer apps, more of them later) to free up system resources.
    • A foreground service
      • Not be killed by the OS, but requires an ongoing Notification to be displayed in the Notification bar while it is running so that the user is aware that the foreground Service is active and will not be killed automatically by the OS.
      • ex: music player.

* IntentService extends Service
  • Service + Handler + HandlerThread。
  • Will receive a single Intent and then shut down automatically once we have processed it.
  • 和 Service 不同,此 api 會執行在自己的 worker thread,陸續執行交給它的 request,但只會有一個 worker thread 同時也只會執行一個 request,當執行完後會自行停止。
  • 實做其 onHandleIntent(Intent intent),在這裡處理 request。
  • 是設計用來可以在一個 Service 中服務多項工作,因此在 onHandleIntent(),不可以呼叫 stopSelf(),全部工作結束,它會自行停止。
  • start service -> send message to handler that has non-UI thread looper -> handlerMessage() -> onHandleIntent()
    • Looper 就是訊息迴圈 (message loop),這是 Android UI 在處理各式訊息時,最重要的元件之一。
  • One word of warning:
    • Performing long tasks in an IntentService does have the inherent risk that it will stop if the device goes to sleep. You can prevent this from happening by holding a WakeLock while onHandleIntent() is executing. Just make sure you release it before onHandleIntent() returns. Alternatively use Mark Murphy’s WakefulIntentServicepattern.

* Pending
  • StrictMode
    • API level 9。
    • 可用於發現潛在問題,ex: 你該使用 background thread 的動作。
  • Loader
    • API level 11。


* Reference
- Background Tasks – Part 1 (Introduction)
- Background Tasks – Part 2 (Worker thread, Handler)
- Background Tasks – Part 3 (AsyncTask)
- Background Tasks – Part 4 (Loader)
- Background Tasks – Part 5 (Service)
- Background Tasks – Part 6 (IntentService)
- Android之Service与IntentService的比较 - HiPhoneZhu的专栏 - 博客频道 - CSDN.NET **
- 深入研究 IntentService 原始碼 ***
- IntentService的功用
- Android Handler 筆記 **
- Java Artisan: Android AsyncTask 與 Handler Thread 的差異 **
- Java Artisan: 在 Android 裡使用 Local Service