2013年6月30日 星期日

xcode storybaord符合3inch 與4inch iphone

使用不同storyboard for 3inch 4inch設置,

可以參考這篇


主要是在 (Appdelegate.m)

@implementation Appdelegate的上方加入

>
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:(v) options:NSNumericSearch] != NSOrderedAscending)


再到此內
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

}

加入



- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  // 1
  UIStoryboard *mainStoryboard = nil;
  if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {
    mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
  } else {
    mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard-legacy" bundle:nil];
  }
 
  // 2
  self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  self.window.rootViewController = [mainStoryboard instantiateInitialViewController];
  [self.window makeKeyAndVisible];
 
  return YES;
}



當然這之前你先在storyboard.storyboard點選,選擇上方的file -> Duplicate

2013年6月20日 星期四

ConcurrentMap使用

import java.util.concurrent.*;

public class TestThread{

    public static void main(String[] args)
    {
        ConcurrentMap myMap = new ConcurrentHashMap();
     Object o = new Object();
     o = myMap.putIfAbsent("1", "one");
     System.out.println( o );
     o = myMap.putIfAbsent("2", "two");
     System.out.println( o );
     o = myMap.putIfAbsent("3", "333");
     System.out.println( o );
     o = myMap.putIfAbsent("3", "3");
     System.out.println( o );
     System.out.println( myMap );
    }

}

回傳

null
null
null
333
{1=one, 3=333, 2=two}


使用putIfAbsent 可以發現若前面有key相同的話,則不會覆蓋之前的key value,

並且回傳333也就是之前相同key的value。

API文件:


putIfAbsent
public V putIfAbsent(K key,
            V value)
If the specified key is not already associated with a value, associate it with the given value. This is equivalent to
   if (!map.containsKey(key))
       return map.put(key, value);
   else
       return map.get(key);
except that the action is performed atomically.
Specified by:
putIfAbsent in interface ConcurrentMap
Parameters:
key - key with which the specified value is to be associated
value - value to be associated with the specified key
Returns:
the previous value associated with the specified key, or null if there was no mapping for the key
Throws:
NullPointerException - if the specified key or value is null

2013年6月18日 星期二

Thread(1)

Thread:

一開始執行Thread,會有自己的stack記憶體,

儲存程式的區域變數。

main本身就為一個執行緒,

我們可以使用Thread.currentThread().getName()來取得執行緒的名稱。



public class Demo{

    public static void main(String[] args)
    {
     
     for( int i = 0 ; i < 30 ; i++ )
     {
      try{
       Thread.sleep(500);
       System.out.println("i: " + i  +"/ " + Thread.currentThread().getName() );
      }
      catch(Exception ex){
   
       System.out.println("err:" + ex );
   
      }
     }
    }

}



可以由此得到 thread的名稱為 main

接下來可以建立一個MyRunner的class,

去implement Runnable interface,

若不去implement的話,可以去extends Thread並override run()也是可以。



public class MyRunner implements Runnable{

 int i = 0;

 @Override
 public void run()
 {
  while(true)
  {
   try{
    Thread.sleep(500);
    System.out.println( "i:" + i++  + "/" + Thread.currentThread().getName() );

    if( i == 20 )
    {
     break;
    }
   }
   catch(Exception ex)
   {

   }
   

  }
 }
}



然後再建一個Demo.java去產生MyRunner的instance來進行測試。



public class Demo{

    public static void main(String[] args)
    {
     
     
        MyRunner r = new MyRunner();
        Thread t1 = new Thread(r);
        t1.run();
     
for( int i = 0 ; i < 30 ; i++ )
     {
      try{
       Thread.sleep(500);
       System.out.println("m: " + i  +"/ " + Thread.currentThread().getName() );
      }
      catch(Exception ex){
   
       System.out.println("err:" + ex );
   
      }
     }
    }

}



由這裡可以發現,我是用t1.run();來執行,

其實是故意的,從這個log我們可以看見

會先產生



i: 0/main
i: 1/main
i: 2/main
i: 3/main
    ‧


i: 19/main
m:0/main



m:29/main


上面的點點點就自己以此類推,

會發現居然thread的名稱都是main ,

因為我們用run()來跑,所以其實不是多建立一個thread,

他還是以main單執行緒來進行,

若要開一條新的thread的話,

我們要把

t1.run();  改成 t1.start();

再執行一次會發現變下面的log:



m: 0/ main
i:0/Thread-1
i:1/Thread-1
m: 1/ main
i:2/Thread-1
m: 2/ main
i:3/Thread-1
m: 3/ main
i:4/Thread-1
m: 4/ main
i:5/Thread-1
m: 5/ main
i:6/Thread-1
m: 6/ main
i:7/Thread-1
m: 7/ main
m: 8/ main
i:8/Thread-1
i:9/Thread-1
m: 9/ main
i:10/Thread-1
m: 10/ main
m: 11/ main
i:11/Thread-1
i:12/Thread-1



會發現thread的名稱多了一個Thread-1,

在開thread的預設名稱會以thread-編號,

當然我們可以自己定義Thread的名稱:

依上面的程式可以利用

t1.setName("自訂Thread名稱");

或用

Thread t1 = new Thread(r, "自訂Thread名稱");


接下來我們改變一下Demo.java


public class Demo{

    public static void main(String[] args)
    {
     
     
        MyRunner r = new MyRunner();
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        t1.start();
        t2.start();
     
    }

}


可以發現log:



i:0/Thread-1
i:1/Thread-2
i:2/Thread-2
i:3/Thread-1
i:5/Thread-1
i:4/Thread-2
i:6/Thread-2
i:6/Thread-1
i:7/Thread-1
i:8/Thread-2
i:9/Thread-1
i:10/Thread-2
i:11/Thread-2
i:12/Thread-1
i:13/Thread-2
i:14/Thread-1
i:15/Thread-1
i:15/Thread-2
i:16/Thread-2
i:17/Thread-1
i:18/Thread-2
i:19/Thread-1



i的variable被共享了,所以在執行緒內的資源是可以共享的,

並且是Thread-safe。
☆轉載請註明出處

2013年6月10日 星期一

android dialog

此文章您無權限 呼叫 getAlertDialog("警告", "請輸入帳號").show();



private AlertDialog getAlertDialog(String title, String message){

        //產生一個Builder物件

        Builder builder = new AlertDialog.Builder(this);
        //設定Dialog的標題
        builder.setIcon(R.drawable.alert_icon);
        builder.setTitle(title);
        //設定Dialog的內容
        builder.setMessage(message);
        //設定Positive按鈕資料
        builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
               
            }
        });
        //利用Builder物件建立AlertDialog
        return builder.create();

    }