Thursday, May 28, 2015

Introduction to Xcode


How to add images in Xcode:
New Group images(in fact it shows as a folder)->drag the images to that group->select "copy to destination" in the pop-up window

How to add a new tab to tab bar controller:
drag a view controller to the stroyboard->right click the tab bar controller->(鼠标在黑龙江后面那个点会出现add)add new view controller and connect it to the new controller by dragging a line.


Create a plist:
http://nscookbook.com/2013/02/ios-programming-recipe-13-using-property-lists-plists/

Tuesday, May 19, 2015

Android加密算法: java变成jar然后到dll

Android用定制的BouncyCastle (轻量级加密算法)并且去除key长度限制

1. Java AES encrypt example:

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

public class Encryptor {
    public static String encrypt(String key1, String key2, String value) {
        try {
            IvParameterSpec iv = new IvParameterSpec(key2.getBytes("UTF-8"));

            SecretKeySpec skeySpec = new SecretKeySpec(key1.getBytes("UTF-8"),
                    "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(value.getBytes());
            System.out.println("encrypted string:"
                    + Base64.encodeBase64String(encrypted));
            return Base64.encodeBase64String(encrypted);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static String decrypt(String key1, String key2, String encrypted) {
        try {
            IvParameterSpec iv = new IvParameterSpec(key2.getBytes("UTF-8"));

            SecretKeySpec skeySpec = new SecretKeySpec(key1.getBytes("UTF-8"),
                    "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));

            return new String(original);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {

        String key1 = "Bar12345Bar12345"; // 128 bit key
        String key2 = "ThisIsASecretKet";
        System.out.println(decrypt(key1, key2,
                encrypt(key1, key2, "Hello World")));
    }
}

2. JCE Unlimited Strength installation (java JCE download):
http://stackoverflow.com/questions/6363801/invalidkeyexception-illegal-key-size-java-code-throwing-exception-for-encryp
将local_policy.jar & US_export_policy.jar覆盖JRE security文件夹中的原始jar

3. How to export jar file in Eclipse (non-runnable jar):

if your code refers other libs, you need to copy the lib's source code in the src folder and compile together and can't use it as a jar reference.


4. convert jar to dll/exe for .Net by ikvm:

Ref:
http://stackoverflow.com/questions/15554296/simple-java-aes-encrypt-decrypt-example

Sunday, May 17, 2015

Design pattern 设计模式

Singleton pattern

Factory method/Abstract Factory pattern

Command pattern

Observer pattern

Provider design patter

Producer-consumer


singleton单例模式

顾名思义,就是一个class只能有一个instance。这是用得比较多的模式,场合主要是Util, database instance等。实现方法主要有两种:lazy initialization & eager initialization. 区别在于,eager总是产生一个新的instance.




public class SingletonDemo {
    private static SingletonDemo instance = null;
    private SingletonDemo() { }
 
    public static synchronized SingletonDemo getInstance() {
        if (instance == null) {
            instance = new SingletonDemo();
        }
 
        return instance;
    }
}


public class Singleton {
    private static final Singleton INSTANCE = new Singleton();
 
    private Singleton() {}
 
    public static Singleton getInstance() {
        return INSTANCE;
    }
}

Factory method pattern工厂方法/abstract factory pattern抽象工厂

wiki提供的例子,工厂方法,是对单一产品(button)的异化,而抽象工厂是进一步的工厂方法或者是多个产品组合(工厂级别)的异化。



//几个Button类 class Button{/* ...*/} class WinButton extends Button{/* ...*/} class MacButton extends Button{/* ...*/} //它们的工厂类 interface ButtonFactory{ abstract Button createButton(); } class WinButtonFactory implements ButtonFactory{ Button createButton(){ return new WinButton(); } } class MacButtonFactory implements ButtonFactory{ Button createButton(){ return new MacButton(); } }

class Button; // Abstract Class
 
class MacButton: public Button {};
 
class WinButton: public Button {};
 
class Border; // Abstract Class
 
class MacBorder: public Border {};
 
class WinBorder: public Border {};
对应的工厂是这样的
class AbstractFactory {
public:
    virtual Button* CreateButton() =0;
    virtual Border* CreateBorder() =0;
};
 
class MacFactory: public AbstractFactory {
public:
    MacButton* CreateButton() { return new MacButton; }
    MacBorder* CreateBorder() { return new MacBorder; }
};
 
class WinFactory: public AbstractFactory {
public:
    WinButton* CreateButton() { return new WinButton; }
    WinBorder* CreateBorder() { return new WinBorder; }
};

Provider design pattern提供程序模式

提供程序模式是一个简单的模式,主要是为了减少代码复用而提高代码重用率而设计的模式,只在.Net框架中提供。ProviderBase是.Net提供的基础类. 它其实是继承的一种变体,从xml中读取各种继承的类的名字,从而一起调用一个基类方法实现不同类的同一行为。
下面是一个例子,用于得到不同酒店的价格。

public abstract class HotelProviderBase : ProviderBase
{
       int RunId;
       void setProxy(String proxy){}
       public abstract void UpdateHotels(JobRequest request, int runId);
}

public sealed class ExampleHotelProvider : HotelProviderBase
{
       private void UpdateHotel(JobRequest request){}    
}


public abstract class HotelProviderManager
{
         private static void LoadProviders()
        {
                //load class from hotel.xml
                 _providers = new HotelProviderCollection();
                 ProvidersHelper.InstantiateProviders(section.Providers, _providers, typeof(HotelProviderBase));
        }
}


public sealed class HotelManager 
{
        public void onRun()
       {
                  foreach (HotelProviderBase provider in HotelProviderManager.Providers)
                  {
                            if (provider.Enabled)
                            {
                                provider.UpdateHotels(request, (int)Log.RunId);
                            }
                   }
          }
}

hotel.xml
<add name="ExampleHotelProvider"
         type="ExampleHotelProvider"
         siteId="4"
         siteName="http://www.example.com"
         tableName="HotelRates_Example_Hotels">

http://www.cnblogs.com/webabcd/archive/2007/01/22/626479.html

命令模式Command pattern

由wiki里面的定义,命令模式是把action封装起来,方便重复使用。

下面演示一个测试android app基于UiAutomator的程序
1. EventInput: 首先定义event/command的输入参数
2. Events: 一系列的actions
3. Operator: 对应不同的input,invoke相应的action
4. Main class: 列出所有input, 然后operator开始做事

public abstract class EventInput {
public EventInput followingInput;
}

import java.util.ArrayList;
public class ClickEventInput extends EventInput{

protected String target;

//for GetListValues
public ClickEventInput(){}
public ClickEventInput(EventInput followingInput)
{
this.followingInput = followingInput;
}

public ClickEventInput(String target)
{
this(target,null);
}

public ClickEventInput(String target, EventInput followingInput)
{
this.target = target;
this.followingInput = followingInput;
}

}

public class Events {
       protected static Operator op;

protected Events(Operator op)
{
this.op = op;
}

public void Click(UiDevice device, String buttonName, EventInput followingInput) throws UiObjectNotFoundException
{
try
{
 if(new UiObject(new UiSelector().text(buttonName)).exists())
new UiObject(new UiSelector().text(buttonName)).clickAndWaitForNewWindow();

}
    catch(Exception e)
    {
    Util.Log(3, "Can't press button", buttonName+","+e.toString());
    return;
    }

if(followingInput!=null)
  op.InvokeAction(followingInput);
}
}


如果有其他行为,写custom类覆盖
public class CarEvents extends Events{

public CarEvents(Operator op) {
super(op);
}

public void Click(UiDevice device, String buttonName, EventInput followingInput) throws UiObjectNotFoundException
       {
        }
}


public class Operator{

UiDevice device;
EventInput input;

        public void InvokeAction(EventInput input)
{
Class cls = null;
Object value = false;

            Class[] constructorArg = new Class[1];
            constructorArg[0] = Operator.class;
            Object obj = cls.getDeclaredConstructor(constructorArg).newInstance(this);

            if(input instanceof ClickEventInput)
            {
            Method method = null;
                Class[] cArg = new Class[3];
                cArg[0] = UiDevice.class;
                cArg[1] = String.class;
                cArg[2] = EventInput.class;
                
                ClickEventInput cInput = (ClickEventInput)input;
                method = cls.getMethod("Click",cArg);
                method.invoke(obj,device,cInput.target, input.followingInput);
            }

}
}

public class NewCar extends UiAutomatorTestCase {   

public void testDemo() throws UiObjectNotFoundException {   

             EventInput input = new ClickEventInput("MAKE & MODEL",,new SleepEventInput(3));
             Operator op = new Operator(getUiDevice(), input,"Car", CarEvents.class);
             op.Start();
        }
}