From http://tseng-blog.nge-web.net/blog/2009/02/14/implementing-listeners-in-your-android-java-application/
I don't like inline listeners, and only Android 2 and up support Android:onClick in layout XML,
I have to programming under 1.5, this article is very helpful!

 

Implementing Listeners in your Android/Java application

I’ve seen many people asking how to implement Listeners in their applications. Implementing a Listener is quite easy. There are 3 ways to implement an Listener and the have their advantages and disadvantages.

The tree way to implement Listeners are

  • Inline Implementation
  • Using the implements keyword
  • By using variables

We’ll use our good old LoginExample application, created in previous tutorial which can be found at Android: Your first Android Application.

 

Inline Implementation

The first way, to implement an listener is by using Inline Implementation. In Inline Implementations we create an anonymous listener, define and pass it the the setLisener functions in the same step.

We did this already in our First Android Application Tutorial.

01package com.tseng.examples;
02 
03...
04 
05public class LoginExample extends Activity {
06    /** Called when the activity is first created. */
07    @Override
08    public void onCreate(Bundle savedInstanceState) {
09        super.onCreate(savedInstanceState);
10 
11    ...
12 
13        // Set Click Listener
14        btnLogin.setOnClickListener(new OnClickListener() {
15            @Override
16            public void onClick(View v) {
17                // Check Login
18                String username = etUsername.getText().toString();
19                String password = etPassword.getText().toString();
20 
21                if(username.equals("guest") && password.equals("guest")){
22                    lblResult.setText("Login successful.");
23                } else {
24                    lblResult.setText("Login failed. Username and/or password doesn't match.");
25                }
26            }
27        });
28        btnCancel.setOnClickListener(new OnClickListener() {
29            @Override
30            public void onClick(View v) {
31                // Close the application
32                finish();
33            }
34        });
35    }
36}

As we see, we create an anonymous class there by adding { … code … } behind the new OnClickListener interface and implementing the necessary onClick(View v) method.

Advantages

  • Small and tidy
  • Easy to implement
  • Less overhead

Disadvantages

  • Inflexible
  • Can’t be reused
  • Can be a bit harder to maintain

Usage

Inline implementations are usually used for short 1-time methods, for example if you have a button which closes the application or which displays, you don’t need to add an implementation to your class or create a variable, making your code less readable.

Using the “implements” keyword

The second method to implement an Listener is by adding an interface to your base class. In java you can do this by adding “implements Interfacename” to the class declaration.

01package com.tseng.examples;
02 
03...
04 
05public class LoginExampleImplements extends Activity implements OnClickListener {
06 
07    /** Called when the activity is first created. */
08    @Override
09    public void onCreate(Bundle savedInstanceState) {
10        super.onCreate(savedInstanceState);
11 
12    ...       
13 
14        // Set Click Listener
15        btnLogin.setOnClickListener(this);
16        btnCancel.setOnClickListener(this);
17    }
18 
19    @Override
20    public void onClick(View v) {
21        if(v==btnLogin) {
22            // Check Login
23            String username = etUsername.getText().toString();
24            String password = etPassword.getText().toString();
25 
26            if(username.equals("guest") && password.equals("guest")){
27                lblResult.setText("Login successful.");
28            } else {
29                lblResult.setText("Login failed. Username and/or password doesn't match.");
30            }
31        } else if(v==btnCancel) {
32            // Close the application
33            finish();
34        }
35    }
36}

As we can see, the “onClick(View v)” is being declared inside our LoginExample class and additionally we set the listener by passing a reference to our class to by using btnLogin.setOnClickListener(this);. This works, because we implemented this interface within our class public class LoginExampleImplements extends Activity implements OnClickListener. You may also have noticed, that we add the same listener to both buttons. Because both of the buttons use the same listener, we need to differentiate which one was clicked. This can be done by comparing the View v reference with the Button btnLogin reference as seen below:

1if(v==btnLogin) {
2    // Check Login
3    ...
4} else if(v==btnCancel) {
5    // Close the application
6    ...
7}

Advantages

  • Methods/Listener can be reused in many different widgets
  • Code of multiple Listeners is located in the same section of code
  • Can be used to create one method for similar Listeners

Disadvantages

  • Can contain much unnecessary and untidily code, if the actions executed are to different and you have to add an if / elseif / else blocks, making the code hard to read
  • You can only have one implementation of this Listener per class

Usage

This method is best used, when you have multiple widgets/elements using same or similar listeners (i.E. doing a calculation or check on a click or key press). The example above is not the best example on the usage of the implement method. Let’s imagine, you have a calculator and have 14 buttons  and you want to update the formula you entered after every calculator button is pressed, you could implement it in the following way shown below.

01package com.tseng.examples;
02 
03import android.app.Activity;
04import android.os.Bundle;
05import android.view.View;
06import android.view.View.OnClickListener;
07import android.view.View.OnKeyListener;
08import android.widget.Button;
09import android.widget.EditText;
10import android.widget.TextView;
11 
12public class CalculatorExample extends Activity implements OnClickListener {
13    ...
14 
15    @Override
16    public void onClick(View v) {
17        if(v==btnCalculate) {
18            // Parse and calculate formula
19            String formula = etFormula.getText().toString();
20            Double result = performCalculation(formula);
21 
22            // Update the result TextView
23            tvResult.setText(Strint.valueOf(result));
24 
25            // End it as we don't need or want to update the Formula field
26            return;
27        }
28 
29        // Get the button
30        Button button = (Button)v;
31 
32        // Get the String/Button descritpion
33        String strToAppend = button.getText().toString();
34 
35        // Update Formula
36        etFormula.append(strToAppend);
37    }
38}

You could add this Listener to every of the calculators button and only need to define one Listener. When the buttons are clicked, the button text (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +, –, /, * etc.) will be added to the TextView containing the formula. However, if you press the calculate button, it won’t add a = to the formula, but will instead perform the calculation.

Another very good implementation of this is, if you want to validate the input in a TextField altough there are other way in Android by using the TextView.setFilters(…) Method, but this is another topic.

This is best used when you’re creating your own widgets and want to to handle clicks (assuming there are only few clickable elements there)

By using Variables

This one is very similar to the previous one, with the difference that you don’t add the implementation to your class, but instead hold a reference to the Listener in a variable.

In our LoginExample it would look like this

01package com.tseng.examples;
02 
03...
04 
05public class LoginExampleVariableImplementation extends Activity {
06    ...
07 
08    OnClickListener myClickListener = new OnClickListener() {
09        @Override
10        public void onClick(View v) {
11            if(v==btnLogin) {
12                // Check Login
13                String username = etUsername.getText().toString();
14                String password = etPassword.getText().toString();
15 
16                if(username.equals("guest") && password.equals("guest")){
17                    lblResult.setText("Login successful.");
18                } else {
19                    lblResult.setText("Login failed. Username and/or password doesn't match.");
20                }
21            } else if(v==btnCancel) {
22                // Close the application
23                finish();
24            }
25        }
26    };
27 
28    /** Called when the activity is first created. */
29    @Override
30    public void onCreate(Bundle savedInstanceState) {
31        super.onCreate(savedInstanceState);
32 
33    ...
34 
35        // Set Click Listener
36        btnLogin.setOnClickListener(myClickListener);
37        btnCancel.setOnClickListener(myClickListener);
38    }
39 
40}

Basically we create it anonymous Listener with the difference that we hold a reference to it. This allows us to add this Listener to more than only one widget. The main difference to the implements keyword method is, that we can have more than one Listener inside our class declared and use them more than once.

Advantages

  • Can be reused
  • You can have more than one Listener of the same kind in your class
  • You can keep your listeners organized in one place, making your code easier to read

Disadvantages

  • Too many listeners can make the code rather complicated to read

Usage

This is best to use if you have different Listeners for the same action i.e. 2 different OnClickListener which do a completely different task.

Another very important usage for this variant is if you’re implementing your own Listeners to your widgets, you could have a variable which can be assigned by the users of your widgets

01package com.tseng.examples;
02 
03import android.app.Activity;
04import android.os.Bundle;
05import android.view.View;
06import android.view.View.OnClickListener;
07import android.view.View.OnKeyListener;
08import android.widget.Button;
09import android.widget.EditText;
10import android.widget.TextView;
11 
12public class MyWidget extends View {
13    ...
14 
15    OnClickListener myClickListener = null;
16 
17    /** Called when the activity is first created. */
18    @Override
19    public void onCreate(Bundle savedInstanceState) {
20        super.onCreate(savedInstanceState);
21 
22        ...
23 
24    }
25 
26    public void setOnClickListener(OnClickListener listener) {
27        myClickListener = listener;
28    }
29 
30    private onClick(View v) {
31        // Check if Listener was set and call the onClick Method
32        if(myClickListener!=null)
33            myClickListener.onClick(v);
34    }
35    private void handleEventsMethod() {
36        ...
37        // handle clicks
38        onClick(this);
39    }
40}

This allows us to dynamically set the Listener to our widget without knowing what the listener will actually do with the click, as it can be implemented in any way the user or programmer wants it to be.

Summary

So there are no “right” ways to implement a Listener. It all depends on the situation and/or your personal preferences.

Method Recommended usage
Inline Best to use for short and one time only listeners, like closing an application or displaying an message or call another Activity/Dialog
implements-keyword If you have only one listener in your class (i.e. your own widget) or the listeners shares a fairly similar code/task, like the Calculator Example above
Variables If you have many Listeners with very different codebases and tasks or creating your own widget and want to allow your users to handle the events (i.e. click or key press events).


 
Categories: Android | Java

My boss let me do some research on Android, and want to see how effect it need and if many people will download and use it.

after set up development environment, and running the Hello world, My next step is make the GUI look nicely and give my application our icon.

Do some search and find how to assigning a icon to my application:

Assigning an icon to your Android application just takes a minute.  Actually creating the icon may take a bit longer. :P

  1. Create a 48×48 PNG and drop it into /res/drawable.  The name of this file is usually “icon.png”.
  2. Open your AndroidManifest.xml.
  3. Right under the root “manifest” node of the XML, you should see the “application” node.  Add this attribute to “application”. (The “icon” in “@drawable/icon” refers to the file name of the icon.)
    android:icon="@drawable/icon"

Your app is now iconned.

(Posted in Android by MrSqueezles at January 31st, 2009.)


 
Categories: Java | Android

一、通用篇
  1.1 不用new关键词创建类的实例
  1.2 使用非阻塞I/O
  1.3 慎用异常
  1.4 不要重复初始化变量
  1.5 尽量指定类的final修饰符
  1.6 尽量使用局部变量
  1.7 乘法和除法

一、通用篇

  “通用篇”讨论的问题适合于大多数Java应用。

1.1 不用new关键词创建类的实例

  用new关键词创建类的实例时,构造函数链中的所有构造函数都会被自动调用。但如果一个对象实现了Cloneable接口,我们可以调用它的 clone()方法。clone()方法不会调用任何类构造函数。

  在使用设计模式(Design Pattern)的场合,如果用Factory模式创建对象,则改用clone()方法创建新的对象实例非常简单。例如,下面是Factory模式的一个 典型实现:

public static Credit getNewCredit() {
  return new Credit();
}

  改进后的代码使用clone()方法,如下所示:

private static Credit BaseCredit = new Credit();
public static Credit getNewCredit() {
return (Credit) BaseCredit.clone();
}

  上面的思路对于数组处理同样很有用。

1.2 使用非阻塞I/O

  版本较低的JDK不支持非阻塞I/O API。为避免I/O阻塞,一些应用采用了创建大量线程的办法(在较好的情况下,会使用一个缓冲池)。这种技术可以在许多必须支持并发I/O流的应用中见 到,如Web服务器、报价和拍卖应用等。然而,创建Java线程需要相当可观的开销。

  JDK 1.4引入了非阻塞的I/O库(java.nio)。如果应用要求使用版本较早的JDK,在这里有一个支持非阻塞I/O的软件包。

  请参见Sun中国网站的《调整Java的I/O性能》。

1.3 慎用异常

  异常对性能不利。抛出异常首先要创建一个新的对象。Throwable接口的构造函数调用名为fillInStackTrace()的本地 (Native)方法,fillInStackTrace()方法检查堆栈,收集调用跟踪信息。只要有异常被抛出,VM就必须调整调用堆栈,因为在处理过 程中创建了一个新的对象。

  异常只能用于错误处理,不应该用来控制程序流程。

1.4 不要重复初始化变量

  默认情况下,调用类的构造函数时, Java会把变量初始化成确定的值:所有的对象被设置成null,整数变量(byte、short、int、long)设置成0,float和 double变量设置成0.0,逻辑值设置成false。当一个类从另一个类派生时,这一点尤其应该注意,因为用new关键词创建一个对象时,构造函数链 中的所有构造函数都会被自动调用。

1.5 尽量指定类的final修饰符

  带有final修饰符的类是不可派生的。在Java核心API中,有许多应用final的例子,例如java.lang.String。为 String类指定final防止了人们覆盖length()方法。

  另外,如果指定一个类为final,则该类所有的方法都是final。Java编译器会寻找机会内联(inline)所有的final方法(这和具体 的编译器实现有关)。此举能够使性能平均提高50%。

1.6 尽量使用局部变量

  调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快。其他变量,如静态变量、实例变量等,都在堆(Heap)中创 建,速度较慢。另外,依赖于具体的编译器/JVM,局部变量还可能得到进一步优化。请参见《尽可能使用堆栈变量》。

1.7 乘法和除法

  考虑下面的代码:

for (val = 0; val < 100000; val +=5) { alterX = val * 8; myResult = val * 2; }

  用移位操作替代乘法操作可以极大地提高性能。下面是修改后的代码:

for (val = 0; val < 100000; val += 5) { alterX = val << 3; myResult = val << 1; }

  修改后的代码不再做乘以8的操作,而是改用等价的左移3位操作,每左移1位相当于乘以2。相应地,右移1位操作相当于除以2。值得一提的是,虽然移位 操作速度快,但可能使代码比较难于理解,所以最好加上一些注释。


 
Categories: Interview Question | Java

I have a application need authentication to access another application's API, but the API's password  stored in the database was encrypted by 3DES algorithm in Java code. I can access the Key for decrypt the password.
So I had tried some different to get the clear password,
1. Ask for Plain text password
   I got it, for security reason, It can not be used in production.
2. Ask Java team to build a Java WebService  offer the decode service.
   It looks good plan, but need wait for other team's work, I already wait for 1 month.
3. Try to decrypt the password from .net side. 
   I tried, and just proved it not works. So I come here write down what I found.

The reason is simple: the byte array in java and byte in C# are different.
In Java, the byte  is 8 bit signature, value is from -127 to 128.
but in C# the byte is 8 bit non-signature, the correspond Java byte  in C# is sbyte.
I hard code the Key byte array to force all value of key's byte between 0-128 so c# and Java can have same Key.
But unlucky, the same short string "Hello Wei", in Java, the byte array length is 8. but in C# it is 16.

That obviously tell me it is impossible to share key between java and .net application to do de/encryption.

Here are some of my Java  and C# code I wrote in this research.
Java code have BlowFish and 3sdes.

BlowFishAPI.zip (4.16 KB) 
TripleDesFixture.cs (11.38 KB)

Some reference links;
blowfish in .net: http://www.hotpixel.net/software.html
TripleDes Encryption:  click here


 
Categories: Asp.net | Java