[Java] Bubble sort practice

 

class BubbleSort{
	
	private static int HOW_MANY_RANDOM_NUMBER = 200;
	private static int MAX_RANDOM_NUMBER = 1000;

	private static int swap(int n1, int n2){
		return n1;
	}

	private static void bubble(int data[]){
		int cursor=0, index=0;
		for(index=0; index<data.length; index++){
			for(cursor=0; cursor<data.length-index-1; cursor++){
				if(data[cursor] > data[cursor+1]){
					data[cursor+1]= swap(data[cursor], data[cursor]=data[cursor+1]);
				}
			}
		}
	}

	private static void printArray(int data[]){
		System.out.print("[data]: ");
		for(int x : data){
			System.out.print(x+ " ");
		}
		System.out.println();
	}

	private static int[] numberGenerator(int howmany, int howbig){
		int tmp[] = new int[howmany];
		for(int x=0; x<tmp.length; x++){
			tmp[x] = (int)(Math.random()*howbig+1);
		}
		return tmp;
	}

	public static void main(String args[]){
		System.out.println("現在要取"+HOW_MANY_RANDOM_NUMBER+"個 1~"
			+MAX_RANDOM_NUMBER+" 的亂數資料");
		// 取HOW_MANY_RANDOM_NUMBER個 1~MAX_RANDOM_NUMBER 的亂數存進去data陣列中
		int data[]= numberGenerator(HOW_MANY_RANDOM_NUMBER, MAX_RANDOM_NUMBER);
		// 顯示data內的排序
		printArray(data);
		System.out.println("資料經過Bubble Sort之後");
		// 把data用bubble排序過
		bubble(data);
		// 再顯示出來
		printArray(data);
	}
}

練習重點:

1. bubble sort的概念:

將一串數列由小到大排序,像在水中的泡泡一樣,小泡泡浮上去、大泡泡往後排

2. bubble sort的時間複雜度:

最佳時間:O(n)

平均時間:O(n^2)

最差時間:O(n^2)

空間複雜度:O(1) => 指所需要佔用的空間大小,O(1)表示佔用空間固定,不受數列大小影響

代表一串數列經過bubble sort之後,所花的時間,

最好的情況下就是一開始就排好了,不需要再排序,但還是要走過一輪把數列的每個都檢查過一次,所以跟數列的數量一樣(n)

最差的情況就是大小順序完全相反,每個都需要重新排一次,也就是把數列的每個元素(n)都檢查過n*n次

* 如何證明時間複雜度呢?

將數列數量逐漸增加,觀察所需排序時間:

Desktop_—_-bash_—_96×24

Desktop_—_-bash_—_96×24

Desktop_—_-bash_—_96×24

Desktop_—_-bash_—_96×24

3. java的random:

private static int[] numberGenerator(int howmany, int howbig){
		int tmp[] = new int[howmany];
		for(int x=0; x<tmp.length; x++){
			tmp[x] = (int)(Math.random()*howbig+1);
		}
		return tmp;
	}

4. java的swap:

private static int swap(int n1, int n2){
		return n1;
}

要把x和y交換
使用: data[cursor+1]= swap(data[cursor], data[cursor]=data[cursor+1]);
代數簡化版: y= swap(x,x=y);

 

參考:

1. 小殘的城市光廊:http://emn178.pixnet.net/blog/post/93779892-氣泡排序法(bubble-sort)

對於Java新手,要如何開發Android Bluetooth App?

  1. 要寫Java程式,包括Android,一定要先安裝JDK(Java Developement Kit)
    1) 中文教學:http://rx1226.pixnet.net/blog/post/284754793-%5Bandroid-studio%5D-1-1-修改sdk和jdk位置
    2
    ) 前提是先抓 Java SE Development Kit 8u101
    http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
  2. 再來要寫Android App的話,就是要裝Android的開發環境,就是Android studio,怎麼抓?
    google搜尋:android studio download/ install
    – 如果抓下來安裝完後,不會設定、不知道要做什麼
    google搜尋:android studio tutorial / android studio 教學
    範例:http://androidstation.pixnet.net/blog/post/261391402-android-studio入門教學一:安裝和設定
  3. 要注意一點,以前開發android app是用eclipse,近幾年才改成android studio,所以在google時,注意一下google到的開發環境是哪一個,有時候看起來很像
  4. 弄完android studio後,需要安裝sdk(Software developement kit)
    google搜尋:android studio sdk
    範例:http://www.codedata.com.tw/mobile/android-tutorial-the-1st-class-2-android-sdk
所有環境弄好後,也試著把別人的範例程式抓下來,卻不知道如何下手或改寫?
在此我建議可以先從基本元件開始熟悉,我的熟悉方式和流程大約是
  1. 先創一個File-> New project-> empty activity
    – 如果到這邊不知道怎麼做的話,google搜尋:android studio new project
  2. 創好後,瀏覽一下左邊的檔案列表
    MainActivity_java_-_GmailTest_-____Documents_AndroidProject_GmailTest_
    看一看裡面的檔案有哪些,Java資料夾內有MainActivity.java,其他不重要
    再來res資料夾(resource)內有drawable(放圖片的)、layout(App的畫面呈現)、這兩個資料夾最重要,其餘可以之後有用到在學即可
    所以在layout裡,可以看到activity_main.xml檔,他就是App的主畫面,點進去看可以看到
    activity_main_xml_-_GmailTest_-____Documents_AndroidProject_GmailTest_
    可以試著切換Text和Design兩種呈現方式,基本上一開始只需要用Design的模式去做就好,換過去Design後,可以看到你的app畫面出來了
  3. 燒進去手機實體看看
    google搜尋:android studio 燒入手機
    範例:http://chiachiku.pixnet.net/blog/post/60204745-30分鐘做出自己的android-app
    如果
    找不到手機裡的開發人員模式在哪裡
    google搜尋:你的手機品牌 型號 開發人員
    範例:zenfone selfie 開發人員
燒成功後,再來就是試著熟悉元件了,元件就是有Button(按鈕)、TextView(文字方塊)、ImageView(圖片方塊)、EditText(編輯文字方塊)等等,還有很多元件,
但我建議這四個先練習過一次,怎麼練習?
  1. google搜尋:android button 教學
    google搜尋:android textview 教學
    google搜尋:android imageview 教學
    google搜尋:android edittext 教學
  2. 同樣都是照著裡面的程式,先照著打,不要複製貼上
  3. 一樣燒進去手機跑跑看
  4. 以button為例,跑完後,好,開始看網站上的教學,看一下網站上是如何解釋button程式碼的,如果沒有解釋,那再google下一個button教學,多看三、四個教學後,會發現有些共通點,都是寫在MainActivity內的onCreate()裡
  5. 這時,google搜尋:android oncreate
  6. 可以查到android作業系統內是如何控制App的存亡
  7. 再來button程式碼內,也都可以看到onClick
    google搜尋:android button onclick
  8. 可以查到onclick是做什麼的,沒查到就再查別人的教學
  9. 以此類推,把Button, TextView, ImageView, EditText的基礎程式碼學完
再回去看你抓過的Android範例程式碼,會發現你已經看得懂部分程式碼的運作了
以這個google的技巧為基礎,慢慢找出範例程式碼內的運作方式
Android App難的地方在於除了程式語言之外,還有包含作業系統
所以稍微複雜一點的App會用到Thread的概念
google搜尋:Android thread 教學

舉個例子:
可以看到有三個thread:
  1. AcceptThread
  2. ConnectThread
  3. ConnectedThread
都是跟藍芽連接有關的thread,網頁裡介紹的很詳細,可以先試著把程式碼燒進去兩隻手機裡,試跑看看能不能動
能動就來看看我們想改什麼?
假如想要改變成 藍牙圖片分享器
那麼可以想像,
應該要把原本藍牙聊天室的textview和edittext 改成 imageview和選取圖片的button
這時,就可以google: android button 選圖片

More practice for multi-thread in java (join)

1. join:

class test2{
public static void main(String[] args){
System.out.println(“Hello test2”);
bThread thread1 = new bThread();
bThread thread2 = new bThread();
bThread thread3 = new bThread();
bThread thread4 = new bThread();
Thread thread1b = new Thread(thread1);
Thread thread2b = new Thread(thread2);
Thread thread3b = new Thread(thread3);
Thread thread4b = new Thread(thread4);

thread1b.start();
thread2b.start();
thread3b.start();
thread4b.start();
        System.out.println(“Thread count: “+ Thread.activeCount());
        
        try{
            thread1b.join(); //wait for thread1 join main thread
            System.out.println(thread1b +” join ~~~~~~”);
            thread2b.join();
            System.out.println(thread2b +” join ~~~~~~”);
            thread3b.join();
            System.out.println(thread3b +” join ~~~~~~”);
            thread4b.join();
            System.out.println(thread4b +” join ~~~~~~”);
            
        }catch(InterruptedException e){
            System.out.println(“join error”);
        }

System.out.println(“Thread count: “+ Thread.activeCount());
}
}

class bThread implements Runnable{
public void run(){
for(int i=0; i<100; i++){
String threadName = Thread.currentThread().getName();
System.out.println(threadName+ “: “+ i);
        }
}
public bThread(){
System.out.println(“This is bThread!”);
}

}


執行結果:

herongsendeMacBook-Air:160704-multithread RongSonHo$ java test2
Hello test2
This is bThread!
This is bThread!
This is bThread!
This is bThread!
Thread-0: 0
Thread count: 5
Thread-3: 0
Thread-2: 0
Thread-1: 0
Thread-1: 1
Thread-1: 2
Thread-2: 1
Thread-3: 1
Thread-0: 1
Thread-3: 2
Thread-2: 2
Thread-1: 3
Thread-2: 3
Thread-3: 3
Thread-0: 2
Thread-3: 4
Thread-2: 4
Thread-2: 5
Thread-2: 6
Thread-1: 4
Thread-2: 7
Thread-3: 5
Thread-0: 3
Thread-3: 6
Thread-2: 8
Thread-1: 5
Thread-2: 9
Thread-3: 7
Thread-0: 4
Thread-3: 8
Thread-2: 10
Thread-1: 6
Thread-2: 11
Thread-3: 9
Thread-0: 5
Thread-3: 10
Thread-2: 12
Thread-1: 7
Thread-2: 13
Thread-3: 11
Thread-0: 6
Thread-3: 12
Thread-2: 14
Thread-1: 8
Thread-2: 15
Thread-2: 16
Thread-3: 13
Thread-0: 7
Thread-3: 14
Thread-2: 17
Thread-1: 9
Thread-2: 18
Thread-3: 15
Thread-0: 8
Thread-3: 16
Thread-2: 19
Thread-1: 10
Thread-1: 11
Thread-1: 12
Thread-2: 20
Thread-3: 17
Thread-0: 9
Thread-3: 18
Thread-2: 21
Thread-1: 13
Thread-2: 22
Thread-3: 19
Thread-0: 10
Thread-3: 20
Thread-2: 23
Thread-1: 14
Thread-2: 24
Thread-3: 21
Thread-0: 11
Thread-3: 22
Thread-2: 25
Thread-1: 15
Thread-2: 26
Thread-3: 23
Thread-0: 12
Thread-3: 24
Thread-2: 27
Thread-1: 16
Thread-2: 28
Thread-3: 25
Thread-0: 13
Thread-3: 26
Thread-2: 29
Thread-1: 17
Thread-2: 30
Thread-3: 27
Thread-0: 14
Thread-0: 15
Thread-0: 16
Thread-3: 28
Thread-2: 31
Thread-1: 18
Thread-2: 32
Thread-3: 29
Thread-0: 17
Thread-0: 18
Thread-3: 30
Thread-2: 33
Thread-1: 19
Thread-2: 34
Thread-3: 31
Thread-0: 19
Thread-3: 32
Thread-2: 35
Thread-1: 20
Thread-2: 36
Thread-3: 33
Thread-0: 20
Thread-3: 34
Thread-2: 37
Thread-1: 21
Thread-2: 38
Thread-3: 35
Thread-0: 21
Thread-3: 36
Thread-2: 39
Thread-1: 22
Thread-2: 40
Thread-3: 37
Thread-0: 22
Thread-3: 38
Thread-2: 41
Thread-1: 23
Thread-2: 42
Thread-3: 39
Thread-0: 23
Thread-3: 40
Thread-2: 43
Thread-1: 24
Thread-2: 44
Thread-2: 45
Thread-3: 41
Thread-0: 24
Thread-3: 42
Thread-3: 43
Thread-3: 44
Thread-2: 46
Thread-1: 25
Thread-2: 47
Thread-2: 48
Thread-3: 45
Thread-0: 25
Thread-3: 46
Thread-2: 49
Thread-1: 26
Thread-2: 50
Thread-3: 47
Thread-0: 26
Thread-3: 48
Thread-2: 51
Thread-1: 27
Thread-2: 52
Thread-3: 49
Thread-0: 27
Thread-3: 50
Thread-2: 53
Thread-1: 28
Thread-1: 29
Thread-2: 54
Thread-3: 51
Thread-0: 28
Thread-3: 52
Thread-2: 55
Thread-1: 30
Thread-2: 56
Thread-3: 53
Thread-0: 29
Thread-0: 30
Thread-3: 54
Thread-2: 57
Thread-1: 31
Thread-2: 58
Thread-3: 55
Thread-0: 31
Thread-3: 56
Thread-2: 59
Thread-1: 32
Thread-2: 60
Thread-3: 57
Thread-0: 32
Thread-3: 58
Thread-2: 61
Thread-1: 33
Thread-2: 62
Thread-3: 59
Thread-0: 33
Thread-3: 60
Thread-2: 63
Thread-1: 34
Thread-2: 64
Thread-2: 65
Thread-3: 61
Thread-0: 34
Thread-3: 62
Thread-2: 66
Thread-1: 35
Thread-2: 67
Thread-2: 68
Thread-3: 63
Thread-0: 35
Thread-3: 64
Thread-2: 69
Thread-1: 36
Thread-1: 37
Thread-2: 70
Thread-3: 65
Thread-3: 66
Thread-3: 67
Thread-3: 68
Thread-0: 36
Thread-3: 69
Thread-2: 71
Thread-1: 38
Thread-2: 72
Thread-3: 70
Thread-0: 37
Thread-3: 71
Thread-3: 72
Thread-3: 73
Thread-2: 73
Thread-1: 39
Thread-2: 74
Thread-3: 74
Thread-0: 38
Thread-3: 75
Thread-2: 75
Thread-1: 40
Thread-2: 76
Thread-3: 76
Thread-3: 77
Thread-0: 39
Thread-3: 78
Thread-2: 77
Thread-1: 41
Thread-1: 42
Thread-2: 78
Thread-3: 79
Thread-0: 40
Thread-3: 80
Thread-2: 79
Thread-1: 43
Thread-2: 80
Thread-3: 81
Thread-3: 82
Thread-0: 41
Thread-3: 83
Thread-2: 81
Thread-1: 44
Thread-2: 82
Thread-3: 84
Thread-0: 42
Thread-3: 85
Thread-2: 83
Thread-1: 45
Thread-2: 84
Thread-3: 86
Thread-0: 43
Thread-3: 87
Thread-2: 85
Thread-1: 46
Thread-2: 86
Thread-3: 88
Thread-0: 44
Thread-3: 89
Thread-2: 87
Thread-1: 47
Thread-2: 88
Thread-3: 90
Thread-0: 45
Thread-3: 91
Thread-2: 89
Thread-1: 48
Thread-1: 49
Thread-1: 50
Thread-2: 90
Thread-3: 92
Thread-0: 46
Thread-3: 93
Thread-2: 91
Thread-1: 51
Thread-1: 52
Thread-2: 92
Thread-3: 94
Thread-0: 47
Thread-3: 95
Thread-2: 93
Thread-1: 53
Thread-2: 94
Thread-3: 96
Thread-0: 48
Thread-3: 97
Thread-0: 49
Thread-2: 95
Thread-1: 54
Thread-2: 96
Thread-0: 50
Thread-3: 98
Thread-0: 51
Thread-2: 97
Thread-1: 55
Thread-1: 56
Thread-2: 98
Thread-0: 52
Thread-3: 99
Thread-0: 53
Thread-0: 54
Thread-2: 99
Thread-1: 57
Thread-0: 55
Thread-0: 56
Thread-1: 58
Thread-0: 57
Thread-0: 58
Thread-1: 59
Thread-0: 59
Thread-0: 60
Thread-0: 61
Thread-1: 60
Thread-0: 62
Thread-0: 63
Thread-0: 64
Thread-1: 61
Thread-1: 62
Thread-0: 65
Thread-0: 66
Thread-0: 67
Thread-1: 63
Thread-0: 68
Thread-1: 64
Thread-0: 69
Thread-0: 70
Thread-1: 65
Thread-1: 66
Thread-0: 71
Thread-1: 67
Thread-0: 72
Thread-0: 73
Thread-1: 68
Thread-0: 74
Thread-1: 69
Thread-0: 75
Thread-1: 70
Thread-1: 71
Thread-0: 76
Thread-1: 72
Thread-0: 77
Thread-0: 78
Thread-0: 79
Thread-1: 73
Thread-0: 80
Thread-1: 74
Thread-1: 75
Thread-1: 76
Thread-0: 81
Thread-1: 77
Thread-0: 82
Thread-0: 83
Thread-1: 78
Thread-0: 84
Thread-1: 79
Thread-0: 85
Thread-0: 86
Thread-1: 80
Thread-0: 87
Thread-1: 81
Thread-1: 82
Thread-0: 88
Thread-0: 89
Thread-1: 83
Thread-0: 90
Thread-1: 84
Thread-1: 85
Thread-0: 91
Thread-1: 86
Thread-0: 92
Thread-1: 87
Thread-1: 88
Thread-0: 93
Thread-1: 89
Thread-1: 90
Thread-1: 91
Thread-0: 94
Thread-0: 95
Thread-1: 92
Thread-0: 96
Thread-0: 97
Thread-0: 98
Thread-1: 93
Thread-0: 99
Thread-1: 94
Thread-1: 95
Thread[Thread-0,5,] join ~~~~~~
Thread-1: 96
Thread-1: 97
Thread-1: 98
Thread-1: 99
Thread[Thread-1,5,] join ~~~~~~
Thread[Thread-2,5,] join ~~~~~~
Thread[Thread-3,5,] join ~~~~~~
Thread count: 1

———————


herongsendeMacBook-Air:160704-multithread RongSonHo$ java test2
Hello test2
This is bThread!
This is bThread!
This is bThread!
This is bThread!
Thread-0: 0
Thread-0: 1
Thread-1: 0
Thread-1: 1
Thread-2: 0
Thread-0: 2
Thread-2: 1
Thread-2: 2
Thread-1: 2
Thread-1: 3
Thread-3: 0
Thread-2: 3
Thread-0: 3
Thread-2: 4
Thread-3: 1
Thread-1: 4
Thread-3: 2
Thread-2: 5
Thread-0: 4
Thread-2: 6
Thread-3: 3
Thread-1: 5
Thread-3: 4
Thread-2: 7
Thread-0: 5
Thread-2: 8
Thread-3: 5
Thread-1: 6
Thread-3: 6
Thread-2: 9
Thread-0: 6
Thread-2: 10
Thread-3: 7
Thread-1: 7
Thread-3: 8
Thread-2: 11
Thread-0: 7
Thread-2: 12
Thread-3: 9
Thread-1: 8
Thread-3: 10
Thread-2: 13
Thread-0: 8
Thread-2: 14
Thread-3: 11
Thread-1: 9
Thread-3: 12
Thread-2: 15
Thread-0: 9
Thread-2: 16
Thread-3: 13
Thread-1: 10
Thread-3: 14
Thread-2: 17
Thread-2: 18
Thread-0: 10
Thread-2: 19
Thread-2: 20
Thread-3: 15
Thread-1: 11
Thread-3: 16
Thread-2: 21
Thread-0: 11
Thread-2: 22
Thread-2: 23
Thread-2: 24
Thread-2: 25
Thread-3: 17
Thread-3: 18
Thread-3: 19
Thread-3: 20
Thread-3: 21
Thread-3: 22
Thread-1: 12
Thread-3: 23
Thread-2: 26
Thread-0: 12
Thread-2: 27
Thread-3: 24
Thread-1: 13
Thread-3: 25
Thread-2: 28
Thread-0: 13
Thread-2: 29
Thread-3: 26
Thread-1: 14
Thread-3: 27
Thread-2: 30
Thread-0: 14
Thread-2: 31
Thread-3: 28
Thread-1: 15
Thread-3: 29
Thread-3: 30
Thread-2: 32
Thread-0: 15
Thread-2: 33
Thread-3: 31
Thread-1: 16
Thread-3: 32
Thread-2: 34
Thread-0: 16
Thread-2: 35
Thread-3: 33
Thread-1: 17
Thread-3: 34
Thread-2: 36
Thread-0: 17
Thread-0: 18
Thread-2: 37
Thread-3: 35
Thread-1: 18
Thread-3: 36
Thread-2: 38
Thread-0: 19
Thread-2: 39
Thread-2: 40
Thread-3: 37
Thread-1: 19
Thread-3: 38
Thread-3: 39
Thread-2: 41
Thread-0: 20
Thread-2: 42
Thread-3: 40
Thread-1: 20
Thread-3: 41
Thread-3: 42
Thread-2: 43
Thread-0: 21
Thread-2: 44
Thread-3: 43
Thread-1: 21
Thread-3: 44
Thread-2: 45
Thread-0: 22
Thread-2: 46
Thread-3: 45
Thread-1: 22
Thread-3: 46
Thread-2: 47
Thread-0: 23
Thread-2: 48
Thread-3: 47
Thread-3: 48
Thread-1: 23
Thread-1: 24
Thread-3: 49
Thread-2: 49
Thread-0: 24
Thread-2: 50
Thread-3: 50
Thread-1: 25
Thread-3: 51
Thread-2: 51
Thread-0: 25
Thread-2: 52
Thread-3: 52
Thread-1: 26
Thread-3: 53
Thread-2: 53
Thread-0: 26
Thread-2: 54
Thread-3: 54
Thread-1: 27
Thread-3: 55
Thread-2: 55
Thread-0: 27
Thread-2: 56
Thread-3: 56
Thread-1: 28
Thread-3: 57
Thread-2: 57
Thread-0: 28
Thread-0: 29
Thread-2: 58
Thread-3: 58
Thread-1: 29
Thread-3: 59
Thread-3: 60
Thread-2: 59
Thread-0: 30
Thread-2: 60
Thread-2: 61
Thread-3: 61
Thread-1: 30
Thread-1: 31
Thread-3: 62
Thread-3: 63
Thread-2: 62
Thread-0: 31
Thread-0: 32
Thread-2: 63
Thread-3: 64
Thread-1: 32
Thread-3: 65
Thread-2: 64
Thread-0: 33
Thread-2: 65
Thread-2: 66
Thread-3: 66
Thread-1: 33
Thread-1: 34
Thread-3: 67
Thread-2: 67
Thread-0: 34
Thread-2: 68
Thread-3: 68
Thread-3: 69
Thread-1: 35
Thread-1: 36
Thread-3: 70
Thread-2: 69
Thread-0: 35
Thread-2: 70
Thread-3: 71
Thread-1: 37
Thread-3: 72
Thread-2: 71
Thread-0: 36
Thread-2: 72
Thread-3: 73
Thread-1: 38
Thread-3: 74
Thread-3: 75
Thread-2: 73
Thread-0: 37
Thread-2: 74
Thread-3: 76
Thread-1: 39
Thread-3: 77
Thread-2: 75
Thread-0: 38
Thread-0: 39
Thread-2: 76
Thread-3: 78
Thread-3: 79
Thread-1: 40
Thread-3: 80
Thread-3: 81
Thread-2: 77
Thread-0: 40
Thread-2: 78
Thread-3: 82
Thread-1: 41
Thread-1: 42
Thread-1: 43
Thread-3: 83
Thread-2: 79
Thread-0: 41
Thread-2: 80
Thread-3: 84
Thread-1: 44
Thread-3: 85
Thread-2: 81
Thread-0: 42
Thread-2: 82
Thread-3: 86
Thread-1: 45
Thread-3: 87
Thread-2: 83
Thread-0: 43
Thread-2: 84
Thread-3: 88
Thread-1: 46
Thread-3: 89
Thread-2: 85
Thread-0: 44
Thread-0: 45
Thread-2: 86
Thread-3: 90
Thread-1: 47
Thread-3: 91
Thread-2: 87
Thread-0: 46
Thread-2: 88
Thread-3: 92
Thread-1: 48
Thread-3: 93
Thread-2: 89
Thread-0: 47
Thread-2: 90
Thread-3: 94
Thread-1: 49
Thread-3: 95
Thread-2: 91
Thread-0: 48
Thread-0: 49
Thread-2: 92
Thread-3: 96
Thread-1: 50
Thread-1: 51
Thread-3: 97
Thread-2: 93
Thread-0: 50
Thread-2: 94
Thread-3: 98
Thread-1: 52
Thread-3: 99
Thread-2: 95
Thread-0: 51
Thread-2: 96
Thread-1: 53
Thread-2: 97
Thread-0: 52
Thread-2: 98
Thread-1: 54
Thread-2: 99
Thread-0: 53
Thread-1: 55
Thread-1: 56
Thread-0: 54
Thread-0: 55
Thread-1: 57
Thread-0: 56
Thread-0: 57
Thread-1: 58
Thread-0: 58
Thread-1: 59
Thread-0: 59
Thread-1: 60
Thread-1: 61
Thread-0: 60
Thread-1: 62
Thread-0: 61
Thread-0: 62
Thread-1: 63
Thread-0: 63
Thread-0: 64
Thread-1: 64
Thread-0: 65
Thread-1: 65
Thread-0: 66
Thread-0: 67
Thread-1: 66
Thread-0: 68
Thread-1: 67
Thread-0: 69
Thread-1: 68
Thread-0: 70
Thread-0: 71
Thread-1: 69
Thread-1: 70
Thread-0: 72
Thread-1: 71
Thread-0: 73
Thread-1: 72
Thread-0: 74
Thread-1: 73
Thread-1: 74
Thread-0: 75
Thread-0: 76
Thread-1: 75
Thread-0: 77
Thread-1: 76
Thread-1: 77
Thread-0: 78
Thread-1: 78
Thread-1: 79
Thread-0: 79
Thread-0: 80
Thread-1: 80
Thread-0: 81
Thread-1: 81
Thread-1: 82
Thread-0: 82
Thread-0: 83
Thread-0: 84
Thread-1: 83
Thread-0: 85
Thread-1: 84
Thread-0: 86
Thread-0: 87
Thread-1: 85
Thread-1: 86
Thread-0: 88
Thread-1: 87
Thread-1: 88
Thread-0: 89
Thread-1: 89
Thread-0: 90
Thread-0: 91
Thread-1: 90
Thread-0: 92
Thread-0: 93
Thread-1: 91
Thread-1: 92
Thread-0: 94
Thread-1: 93
Thread-0: 95
Thread-1: 94
Thread-0: 96
Thread-0: 97
Thread-0: 98
Thread-1: 95
Thread-0: 99
Thread-1: 96
Thread-1: 97
Thread-1: 98
Thread-1: 99
Thread[Thread-0,5,] join ~~~~~~
Thread[Thread-1,5,] join ~~~~~~
Thread[Thread-2,5,] join ~~~~~~
Thread[Thread-3,5,] join ~~~~~~
Thread count: 1

——————-

herongsendeMacBook-Air:160704-multithread RongSonHo$ java test2
Hello test2
This is bThread!
This is bThread!
This is bThread!
This is bThread!
Thread-1: 0
Thread-1: 1
Thread-1: 2
Thread-1: 3
Thread-1: 4
Thread-1: 5
Thread-0: 0
Thread-2: 0
Thread-0: 1
Thread-1: 6
Thread-3: 0
Thread-3: 1
Thread-1: 7
Thread-0: 2
Thread-2: 1
Thread-0: 3
Thread-0: 4
Thread-1: 8
Thread-3: 2
Thread-3: 3
Thread-1: 9
Thread-1: 10
Thread-0: 5
Thread-2: 2
Thread-2: 3
Thread-0: 6
Thread-0: 7
Thread-1: 11
Thread-3: 4
Thread-1: 12
Thread-0: 8
Thread-2: 4
Thread-0: 9
Thread-1: 13
Thread-3: 5
Thread-1: 14
Thread-0: 10
Thread-2: 5
Thread-2: 6
Thread-0: 11
Thread-1: 15
Thread-3: 6
Thread-1: 16
Thread-0: 12
Thread-2: 7
Thread-2: 8
Thread-0: 13
Thread-0: 14
Thread-1: 17
Thread-1: 18
Thread-3: 7
Thread-1: 19
Thread-1: 20
Thread-0: 15
Thread-0: 16
Thread-0: 17
Thread-0: 18
Thread-0: 19
Thread-0: 20
Thread-0: 21
Thread-0: 22
Thread-0: 23
Thread-0: 24
Thread-0: 25
Thread-0: 26
Thread-0: 27
Thread-2: 9
Thread-0: 28
Thread-0: 29
Thread-0: 30
Thread-0: 31
Thread-1: 21
Thread-1: 22
Thread-3: 8
Thread-1: 23
Thread-1: 24
Thread-0: 32
Thread-0: 33
Thread-0: 34
Thread-2: 10
Thread-0: 35
Thread-0: 36
Thread-0: 37
Thread-2: 11
Thread-2: 12
Thread-2: 13
Thread-2: 14
Thread-2: 15
Thread-2: 16
Thread-2: 17
Thread-2: 18
Thread-2: 19
Thread-2: 20
Thread-1: 25
Thread-1: 26
Thread-1: 27
Thread-1: 28
Thread-1: 29
Thread-1: 30
Thread-1: 31
Thread-1: 32
Thread-1: 33
Thread-1: 34
Thread-1: 35
Thread-1: 36
Thread-1: 37
Thread-1: 38
Thread-1: 39
Thread-1: 40
Thread-1: 41
Thread-3: 9
Thread-3: 10
Thread-3: 11
Thread-3: 12
Thread-1: 42
Thread-2: 21
Thread-0: 38
Thread-2: 22
Thread-1: 43
Thread-3: 13
Thread-1: 44
Thread-1: 45
Thread-1: 46
Thread-2: 23
Thread-0: 39
Thread-0: 40
Thread-0: 41
Thread-0: 42
Thread-0: 43
Thread-0: 44
Thread-0: 45
Thread-2: 24
Thread-1: 47
Thread-1: 48
Thread-3: 14
Thread-1: 49
Thread-2: 25
Thread-0: 46
Thread-2: 26
Thread-1: 50
Thread-3: 15
Thread-1: 51
Thread-2: 27
Thread-0: 47
Thread-2: 28
Thread-1: 52
Thread-1: 53
Thread-3: 16
Thread-1: 54
Thread-2: 29
Thread-0: 48
Thread-2: 30
Thread-1: 55
Thread-3: 17
Thread-1: 56
Thread-2: 31
Thread-0: 49
Thread-2: 32
Thread-1: 57
Thread-1: 58
Thread-3: 18
Thread-3: 19
Thread-1: 59
Thread-2: 33
Thread-0: 50
Thread-2: 34
Thread-1: 60
Thread-3: 20
Thread-1: 61
Thread-2: 35
Thread-0: 51
Thread-2: 36
Thread-1: 62
Thread-3: 21
Thread-1: 63
Thread-2: 37
Thread-0: 52
Thread-2: 38
Thread-1: 64
Thread-3: 22
Thread-1: 65
Thread-2: 39
Thread-0: 53
Thread-2: 40
Thread-1: 66
Thread-3: 23
Thread-1: 67
Thread-2: 41
Thread-2: 42
Thread-0: 54
Thread-2: 43
Thread-2: 44
Thread-1: 68
Thread-3: 24
Thread-1: 69
Thread-2: 45
Thread-0: 55
Thread-2: 46
Thread-1: 70
Thread-3: 25
Thread-3: 26
Thread-1: 71
Thread-2: 47
Thread-0: 56
Thread-2: 48
Thread-1: 72
Thread-3: 27
Thread-1: 73
Thread-2: 49
Thread-0: 57
Thread-2: 50
Thread-1: 74
Thread-3: 28
Thread-1: 75
Thread-2: 51
Thread-0: 58
Thread-2: 52
Thread-1: 76
Thread-3: 29
Thread-1: 77
Thread-2: 53
Thread-0: 59
Thread-2: 54
Thread-1: 78
Thread-3: 30
Thread-1: 79
Thread-2: 55
Thread-0: 60
Thread-2: 56
Thread-1: 80
Thread-3: 31
Thread-1: 81
Thread-2: 57
Thread-0: 61
Thread-2: 58
Thread-1: 82
Thread-1: 83
Thread-3: 32
Thread-1: 84
Thread-2: 59
Thread-2: 60
Thread-0: 62
Thread-2: 61
Thread-1: 85
Thread-3: 33
Thread-1: 86
Thread-2: 62
Thread-0: 63
Thread-2: 63
Thread-1: 87
Thread-3: 34
Thread-1: 88
Thread-2: 64
Thread-0: 64
Thread-2: 65
Thread-1: 89
Thread-3: 35
Thread-1: 90
Thread-2: 66
Thread-0: 65
Thread-2: 67
Thread-1: 91
Thread-3: 36
Thread-1: 92
Thread-2: 68
Thread-0: 66
Thread-2: 69
Thread-1: 93
Thread-3: 37
Thread-1: 94
Thread-2: 70
Thread-0: 67
Thread-2: 71
Thread-1: 95
Thread-3: 38
Thread-1: 96
Thread-2: 72
Thread-0: 68
Thread-2: 73
Thread-1: 97
Thread-3: 39
Thread-1: 98
Thread-2: 74
Thread-0: 69
Thread-2: 75
Thread-1: 99
Thread-3: 40
Thread-2: 76
Thread-2: 77
Thread-0: 70
Thread-2: 78
Thread-3: 41
Thread-2: 79
Thread-0: 71
Thread-2: 80
Thread-3: 42
Thread-2: 81
Thread-0: 72
Thread-2: 82
Thread-3: 43
Thread-2: 83
Thread-0: 73
Thread-2: 84
Thread-3: 44
Thread-2: 85
Thread-2: 86
Thread-2: 87
Thread-0: 74
Thread-2: 88
Thread-3: 45
Thread-3: 46
Thread-3: 47
Thread-2: 89
Thread-0: 75
Thread-2: 90
Thread-2: 91
Thread-2: 92
Thread-3: 48
Thread-2: 93
Thread-0: 76
Thread-0: 77
Thread-0: 78
Thread-2: 94
Thread-3: 49
Thread-2: 95
Thread-0: 79
Thread-0: 80
Thread-2: 96
Thread-2: 97
Thread-3: 50
Thread-2: 98
Thread-2: 99
Thread-0: 81
Thread-3: 51
Thread-0: 82
Thread-3: 52
Thread-0: 83
Thread-0: 84
Thread-0: 85
Thread-3: 53
Thread-0: 86
Thread-3: 54
Thread-0: 87
Thread-0: 88
Thread-0: 89
Thread-3: 55
Thread-0: 90
Thread-0: 91
Thread-3: 56
Thread-3: 57
Thread-0: 92
Thread-0: 93
Thread-3: 58
Thread-3: 59
Thread-3: 60
Thread-3: 61
Thread-3: 62
Thread-3: 63
Thread-3: 64
Thread-3: 65
Thread-3: 66
Thread-3: 67
Thread-3: 68
Thread-0: 94
Thread-3: 69
Thread-0: 95
Thread-0: 96
Thread-3: 70
Thread-0: 97
Thread-3: 71
Thread-0: 98
Thread-0: 99
Thread-3: 72
Thread-3: 73
Thread-3: 74
Thread-3: 75
Thread[Thread-0,5,] join ~~~~~~
Thread[Thread-1,5,] join ~~~~~~
Thread[Thread-2,5,] join ~~~~~~
Thread-3: 76
Thread-3: 77
Thread-3: 78
Thread-3: 79
Thread-3: 80
Thread-3: 81
Thread-3: 82
Thread-3: 83
Thread-3: 84
Thread-3: 85
Thread-3: 86
Thread-3: 87
Thread-3: 88
Thread-3: 89
Thread-3: 90
Thread-3: 91
Thread-3: 92
Thread-3: 93
Thread-3: 94
Thread-3: 95
Thread-3: 96
Thread-3: 97
Thread-3: 98
Thread-3: 99
Thread[Thread-3,5,] join ~~~~~~
Thread count: 1

結論:
依照main裡面thread的join順序,會有所不同
在main裡join的安排順序是thread1, thread2, thread3, thread4
main執行到thread1b.join();時,會一直等到thread1執行結束後,main才會繼續往下跑
thread1結束後,就依此類推到thread2,3,4
所以即使thread2,3,4比thread1先執行完了,也是要先等thread1執行完且也join了
才輪得到2,3,4來join
參考:
1. 執行緒的加入(join):http://openhome.cc/Gossip/JavaGossip-V2/JoinThread.htm

How to create multiThread in java

public class Thread extends Object implements Runnable

有兩種方法,繼承Thread or 實作Runnable

1.  繼承Thread:

class test1{
public static void main(String[] args){
System.out.println(“Hello”);
aThread thread1 = new aThread();
aThread thread2 = new aThread();

thread1.setName(“thread1”);
thread2.setName(“thread2”);
thread1.start();
thread2.start();
System.out.println(Thread.activeCount());
}
}


class aThread extends Thread{
public void run(){
for(int i=0; i<100; i++){
String threadName = Thread.currentThread().getName();
System.out.println(threadName + “: “ + i);
}
}

}

執行結果:
herongsendeMacBook-Air:160704-multithread RongSonHo$ time java test1
Hello
3
thread2: 0
thread1: 0
thread1: 1
thread2: 1
thread1: 2
thread1: 3
thread2: 2
thread2: 3
thread1: 4
thread2: 4
thread1: 5
thread1: 6
thread1: 7
thread1: 8
thread2: 5
thread1: 9
thread2: 6
thread1: 10
thread2: 7
thread1: 11
thread2: 8
thread1: 12
thread2: 9
thread1: 13
thread2: 10
thread1: 14
thread2: 11
thread1: 15
thread2: 12
thread1: 16
thread2: 13
thread1: 17
thread2: 14
thread1: 18
thread2: 15
thread1: 19
thread2: 16
thread1: 20
thread2: 17
thread1: 21
thread2: 18
thread1: 22
thread2: 19
thread1: 23
thread2: 20
thread1: 24
thread2: 21
thread1: 25
thread2: 22
thread1: 26
thread2: 23
thread1: 27
thread2: 24
thread2: 25
thread1: 28
thread2: 26
thread1: 29
thread2: 27
thread1: 30
thread2: 28
thread1: 31
thread2: 29
thread1: 32
thread1: 33
thread1: 34
thread2: 30
thread1: 35
thread1: 36
thread2: 31
thread2: 32
thread1: 37
thread2: 33
thread1: 38
thread1: 39
thread2: 34
thread1: 40
thread2: 35
thread1: 41
thread2: 36
thread1: 42
thread2: 37
thread1: 43
thread2: 38
thread1: 44
thread2: 39
thread1: 45
thread2: 40
thread1: 46
thread2: 41
thread1: 47
thread2: 42
thread1: 48
thread2: 43
thread1: 49
thread2: 44
thread1: 50
thread2: 45
thread1: 51
thread2: 46
thread1: 52
thread2: 47
thread1: 53
thread2: 48
thread1: 54
thread2: 49
thread1: 55
thread2: 50
thread1: 56
thread2: 51
thread1: 57
thread2: 52
thread1: 58
thread2: 53
thread1: 59
thread1: 60
thread2: 54
thread1: 61
thread2: 55
thread1: 62
thread2: 56
thread1: 63
thread2: 57
thread1: 64
thread2: 58
thread1: 65
thread2: 59
thread2: 60
thread1: 66
thread1: 67
thread2: 61
thread1: 68
thread2: 62
thread1: 69
thread2: 63
thread1: 70
thread2: 64
thread1: 71
thread2: 65
thread1: 72
thread2: 66
thread1: 73
thread2: 67
thread1: 74
thread2: 68
thread1: 75
thread2: 69
thread1: 76
thread2: 70
thread1: 77
thread2: 71
thread1: 78
thread2: 72
thread1: 79
thread2: 73
thread1: 80
thread2: 74
thread1: 81
thread2: 75
thread1: 82
thread1: 83
thread2: 76
thread1: 84
thread2: 77
thread1: 85
thread2: 78
thread2: 79
thread1: 86
thread2: 80
thread1: 87
thread2: 81
thread1: 88
thread2: 82
thread1: 89
thread2: 83
thread1: 90
thread1: 91
thread2: 84
thread2: 85
thread1: 92
thread2: 86
thread2: 87
thread1: 93
thread2: 88
thread1: 94
thread2: 89
thread2: 90
thread1: 95
thread2: 91
thread2: 92
thread1: 96
thread2: 93
thread1: 97
thread2: 94
thread1: 98
thread2: 95
thread1: 99
thread2: 96
thread2: 97
thread2: 98
thread2: 99

real 0m0.647s
user 0m0.164s
sys 0m0.153s

2. 實作Runnable

class test2{
public static void main(String[] args){
System.out.println(“Hello test2”);
bThread thread1 = new bThread();
bThread thread2 = new bThread();
bThread thread3 = new bThread();
bThread thread4 = new bThread();
Thread thread1b = new Thread(thread1, “thread1”);
Thread thread2b = new Thread(thread2, “thread2”);
Thread thread3b = new Thread(thread3, “thread3”);
Thread thread4b = new Thread(thread4, “thread4”);

thread1b.start();
thread2b.start();
thread3b.start();
thread4b.start();
System.out.println(“Thread count: “+ Thread.activeCount());
}
}

class bThread implements Runnable{
public void run(){
for(int i=0; i<100; i++){
String threadName = Thread.currentThread().getName();
System.out.println(threadName+ “: “+ i);
}
}
public bThread(){
System.out.println(“This is bThread!”);
}

}

執行結果:
herongsendeMacBook-Air:160704-multithread RongSonHo$ time java test2
Hello test2
This is bThread!
This is bThread!
This is bThread!
This is bThread!
Thread-1: 0
Thread count: 5
Thread-3: 0
Thread-2: 0
Thread-0: 0
Thread-2: 1
Thread-3: 1
Thread-1: 1
Thread-3: 2
Thread-2: 2
Thread-0: 1
Thread-2: 3
Thread-3: 3
Thread-1: 2
Thread-3: 4
Thread-2: 4
Thread-0: 2
Thread-2: 5
Thread-3: 5
Thread-1: 3
Thread-3: 6
Thread-2: 6
Thread-2: 7
Thread-0: 3
Thread-2: 8
Thread-3: 7
Thread-1: 4
Thread-3: 8
Thread-2: 9
Thread-0: 4
Thread-2: 10
Thread-3: 9
Thread-1: 5
Thread-3: 10
Thread-2: 11
Thread-0: 5
Thread-2: 12
Thread-3: 11
Thread-1: 6
Thread-3: 12
Thread-2: 13
Thread-0: 6
Thread-2: 14
Thread-2: 15
Thread-3: 13
Thread-1: 7
Thread-3: 14
Thread-2: 16
Thread-0: 7
Thread-2: 17
Thread-3: 15
Thread-1: 8
Thread-3: 16
Thread-2: 18
Thread-0: 8
Thread-2: 19
Thread-3: 17
Thread-1: 9
Thread-3: 18
Thread-2: 20
Thread-0: 9
Thread-2: 21
Thread-3: 19
Thread-1: 10
Thread-3: 20
Thread-2: 22
Thread-0: 10
Thread-2: 23
Thread-3: 21
Thread-1: 11
Thread-3: 22
Thread-2: 24
Thread-0: 11
Thread-2: 25
Thread-3: 23
Thread-1: 12
Thread-3: 24
Thread-2: 26
Thread-0: 12
Thread-2: 27
Thread-3: 25
Thread-1: 13
Thread-3: 26
Thread-2: 28
Thread-0: 13
Thread-2: 29
Thread-3: 27
Thread-1: 14
Thread-3: 28
Thread-2: 30
Thread-0: 14
Thread-2: 31
Thread-3: 29
Thread-1: 15
Thread-3: 30
Thread-2: 32
Thread-0: 15
Thread-2: 33
Thread-3: 31
Thread-1: 16
Thread-3: 32
Thread-3: 33
Thread-3: 34
Thread-2: 34
Thread-0: 16
Thread-0: 17
Thread-2: 35
Thread-3: 35
Thread-1: 17
Thread-3: 36
Thread-2: 36
Thread-0: 18
Thread-2: 37
Thread-3: 37
Thread-3: 38
Thread-3: 39
Thread-1: 18
Thread-3: 40
Thread-2: 38
Thread-0: 19
Thread-2: 39
Thread-3: 41
Thread-1: 19
Thread-3: 42
Thread-2: 40
Thread-2: 41
Thread-0: 20
Thread-0: 21
Thread-2: 42
Thread-3: 43
Thread-1: 20
Thread-3: 44
Thread-2: 43
Thread-0: 22
Thread-2: 44
Thread-3: 45
Thread-1: 21
Thread-3: 46
Thread-2: 45
Thread-0: 23
Thread-2: 46
Thread-3: 47
Thread-1: 22
Thread-3: 48
Thread-2: 47
Thread-0: 24
Thread-2: 48
Thread-3: 49
Thread-1: 23
Thread-3: 50
Thread-2: 49
Thread-0: 25
Thread-2: 50
Thread-3: 51
Thread-1: 24
Thread-3: 52
Thread-2: 51
Thread-0: 26
Thread-2: 52
Thread-3: 53
Thread-1: 25
Thread-3: 54
Thread-2: 53
Thread-0: 27
Thread-2: 54
Thread-3: 55
Thread-1: 26
Thread-3: 56
Thread-2: 55
Thread-0: 28
Thread-2: 56
Thread-3: 57
Thread-3: 58
Thread-1: 27
Thread-3: 59
Thread-2: 57
Thread-0: 29
Thread-2: 58
Thread-3: 60
Thread-1: 28
Thread-3: 61
Thread-2: 59
Thread-0: 30
Thread-0: 31
Thread-2: 60
Thread-3: 62
Thread-1: 29
Thread-3: 63
Thread-2: 61
Thread-2: 62
Thread-0: 32
Thread-0: 33
Thread-2: 63
Thread-2: 64
Thread-3: 64
Thread-1: 30
Thread-3: 65
Thread-2: 65
Thread-0: 34
Thread-2: 66
Thread-3: 66
Thread-1: 31
Thread-3: 67
Thread-2: 67
Thread-2: 68
Thread-0: 35
Thread-2: 69
Thread-3: 68
Thread-1: 32
Thread-1: 33
Thread-1: 34
Thread-3: 69
Thread-2: 70
Thread-0: 36
Thread-2: 71
Thread-3: 70
Thread-3: 71
Thread-1: 35
Thread-3: 72
Thread-2: 72
Thread-0: 37
Thread-2: 73
Thread-3: 73
Thread-1: 36
Thread-3: 74
Thread-2: 74
Thread-2: 75
Thread-0: 38
Thread-2: 76
Thread-3: 75
Thread-1: 37
Thread-3: 76
Thread-2: 77
Thread-0: 39
Thread-2: 78
Thread-3: 77
Thread-1: 38
Thread-3: 78
Thread-2: 79
Thread-0: 40
Thread-2: 80
Thread-3: 79
Thread-1: 39
Thread-3: 80
Thread-3: 81
Thread-3: 82
Thread-2: 81
Thread-0: 41
Thread-2: 82
Thread-3: 83
Thread-1: 40
Thread-3: 84
Thread-2: 83
Thread-0: 42
Thread-2: 84
Thread-3: 85
Thread-1: 41
Thread-3: 86
Thread-2: 85
Thread-0: 43
Thread-2: 86
Thread-3: 87
Thread-1: 42
Thread-1: 43
Thread-3: 88
Thread-2: 87
Thread-0: 44
Thread-2: 88
Thread-3: 89
Thread-1: 44
Thread-3: 90
Thread-2: 89
Thread-0: 45
Thread-2: 90
Thread-3: 91
Thread-3: 92
Thread-1: 45
Thread-3: 93
Thread-2: 91
Thread-0: 46
Thread-2: 92
Thread-3: 94
Thread-1: 46
Thread-3: 95
Thread-2: 93
Thread-0: 47
Thread-2: 94
Thread-3: 96
Thread-1: 47
Thread-3: 97
Thread-2: 95
Thread-0: 48
Thread-2: 96
Thread-3: 98
Thread-1: 48
Thread-3: 99
Thread-2: 97
Thread-0: 49
Thread-2: 98
Thread-2: 99
Thread-1: 49
Thread-0: 50
Thread-1: 50
Thread-1: 51
Thread-0: 51
Thread-1: 52
Thread-0: 52
Thread-1: 53
Thread-0: 53
Thread-1: 54
Thread-0: 54
Thread-1: 55
Thread-0: 55
Thread-1: 56
Thread-0: 56
Thread-1: 57
Thread-0: 57
Thread-1: 58
Thread-0: 58
Thread-1: 59
Thread-0: 59
Thread-1: 60
Thread-0: 60
Thread-1: 61
Thread-0: 61
Thread-1: 62
Thread-0: 62
Thread-0: 63
Thread-1: 63
Thread-0: 64
Thread-1: 64
Thread-0: 65
Thread-0: 66
Thread-1: 65
Thread-0: 67
Thread-1: 66
Thread-0: 68
Thread-1: 67
Thread-0: 69
Thread-1: 68
Thread-0: 70
Thread-1: 69
Thread-1: 70
Thread-1: 71
Thread-1: 72
Thread-0: 71
Thread-1: 73
Thread-0: 72
Thread-1: 74
Thread-0: 73
Thread-1: 75
Thread-0: 74
Thread-1: 76
Thread-1: 77
Thread-0: 75
Thread-1: 78
Thread-0: 76
Thread-1: 79
Thread-0: 77
Thread-1: 80
Thread-1: 81
Thread-0: 78
Thread-1: 82
Thread-0: 79
Thread-0: 80
Thread-0: 81
Thread-1: 83
Thread-0: 82
Thread-1: 84
Thread-1: 85
Thread-0: 83
Thread-0: 84
Thread-1: 86
Thread-0: 85
Thread-0: 86
Thread-1: 87
Thread-0: 87
Thread-1: 88
Thread-0: 88
Thread-0: 89
Thread-1: 89
Thread-0: 90
Thread-1: 90
Thread-0: 91
Thread-1: 91
Thread-0: 92
Thread-1: 92
Thread-0: 93
Thread-1: 93
Thread-1: 94
Thread-0: 94
Thread-1: 95
Thread-1: 96
Thread-1: 97
Thread-0: 95
Thread-1: 98
Thread-1: 99
Thread-0: 96
Thread-0: 97
Thread-0: 98
Thread-0: 99

real 0m0.457s
user 0m0.179s
sys 0m0.105s

ps. 預設的Thread Name: Thread-0…

Thread的Constructor:
1. Thread() 分派新的執行緒  -> test1.java
2. Thread(String name)3. Thread(Runnable target) 傳入一個Runnable物件,並分派新的執行緒 -> test2.java
4. Thread(Runnable target, String name) 

常用方法:
1. String getName() 取得名稱
2. int getPriority() 取得優先權
3. void setPriority() 可設參數1~10或MIN_PRIORITY=1、NORM_PRIORITY=5、MAX_PRIORITY=10
4. void start 將執行丟入Runnable pool中,等待系統run()呼叫
5. void run() 開始執行工作(由系統自動呼叫,非程式設計師撰寫)
6. static void yield() 將目前執行緒先行暫停,重新排程,讓與其他執行緒執行
7. static void sleep(long millis) 暫停目前執行緒,需在try-catch中呼叫,會丟出throws InterruptedException
8. void join() / void join(long millis) 用於調整執行緒執行順序,先暫停目前執行緒,而指定其他執行緒加入執行工作,執行完畢後才回復,或可設定執行時間,需在try-catch中呼叫,會丟出throws InterruptedException
9. void stop() 停止正在執行的執行緒 (不建議使用,易造成死結)
10. void suspend() 停止正在執行的執行緒 (不建議使用,易造成死結)
11. void destroy() 毀掉執行緒
12. boolean isAlive() 取得目前執行緒狀態
13. void wait() 讓執行緒進入等待狀態
14. void notify() 喚醒一個等待中的執行緒,若有多個執行緒,則由JVM決定
15. void notifyAll() 喚醒所有等待中的執行緒





參考:
1. MEMO 123: JAVA筆記-Thread 多執行緒基本撰寫範例與常用函式 :http://jhengjyun.blogspot.tw/2011/04/1.html

How to pack a Java program into an executable App in MacOS

要在MacOS內變成執行檔,首先要將Java files編譯成.class,再將所有class檔以command方式包裝成jar檔,再以某種固定的路徑包裝成.app的資料夾=> 就會自己變成app檔

1. 將java files編譯成class files
=> javac test.java

2. 把所有.class檔包進.jar檔
=> 1) 寫manifest.mf檔:內容

Main-Class: test

(需要後面空兩行)

=> 2) 以指令方式包成.jar檔
jar cvfm testApp.jar manifest.mf test.class

3. 測試jar可否執行
=> java -jar testApp.jar

(以上如果是有package的話,請參考http://it-easy.tw/java-jar/)

4. 開啟”Automator” => Choose “Application” => Search “AppleScript”
=> Drag “Run AppleScript” to right side

=>
on run {input, parameters}
set p to POSIX path of (path to me)
do shell script “java -jar ” & p & “/Contents/Java/TestApp.jar”
return input

end run

5. 將已做好的.icns檔替換到/Contents/Resources/AutomatorApplet.icns(檔名也要改)

完成圖:

6. AWTtest.java:
import java.awt.*;import java.awt.event.*;
class Attest{ 
public static void main(String[] args) {
        Frame frame = new Frame(“AWTDemo”);
        frame.addWindowListener(new AdapterDemo());
        frame.setLayout(new FlowLayout());
        Button button = new Button(“AWT1”);
        Checkbox checkbox = new Checkbox(“AWT2”);
        Choice choice = new Choice();
        choice.add(“AWT3”);
        Label label = new Label(“AWT4”);
        List list = new List();
        list.add(“AWT5”); 
        TextArea textarea = new TextArea(“AWT6”);
        TextField textfield = new TextField(“AWT7”);
        frame.add(button);
        frame.add(checkbox); 
        frame.add(choice);
        frame.add(label);
        frame.add(list);
        frame.add(textarea);
        frame.add(textfield);
                 frame.pack();
        frame.setVisible(true);
    }
}
class AdapterDemo extends WindowAdapter {
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }
}

參考:
1.
[Java]如何將編譯好的.class檔案打包成JAR?:http://it-easy.tw/java-jar/

2. 

Mac 下開發 Java 程式二三事:http://blog.ericsk.org/archives/317
3.

How to convert .jar to .app on Mac – a Java tutorial:https://www.youtube.com/watch?v=kwdK6Dg1a_Y

PhotoUploader: Using Android socket client send photo to Java socket server

大四下最後一學期 Bo的Java期末project
原本就很想做的socket練習
剛好在這次有機會來實做

project內容:
在Android端從圖片庫裡面選一張圖片(可從圖片庫或相簿裡選擇)
透過socket傳給已經在電腦上開好的Java Server

緣由:
因為每次拍完照要傳照片到電腦收藏都很麻煩
不是透過USB線就是透過雲端或是社群軟體或網站
用USB有時候會讀不到或是還要找線很麻煩
而雲端的容量會不夠放、也不確定安不安全
社群軟體或網站(Line, FB)都會把照片壓縮,畫質變很差,而且要一張一張抓
所以不如自己做一個傳照片的App吧!

Demo圖:



會傳到桌面,命名為socketReceive.jpg
使傳照片變得非常方便的App~~~~

Java Server:

JavaSocketServer.java:

import java.io.FileOutputStream;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class JavaSocketServer implements Runnable {
    
    public static final int SERVERPORT = 5987;
    
    // 最後要儲存照片的位置
    public static final String file_name = “/Users/RongSonHo/Desktop/socketReceive.jpg”;
    public void run() {
        
        try {
            
            System.out.println(“Server: Connecting…”);
            ServerSocket serverSocket = new ServerSocket(SERVERPORT);
            
            while (true) {
                
                Socket client = serverSocket.accept();
                System.out.println(“Server: Receiving…”);
                
                OutputStream out = new FileOutputStream(file_name);
                byte buf[] = new byte[1024];
                int len;
                
                // 讀入從手機端傳來的照片
                InputStream inputStream = client.getInputStream();
                try {
                    while ((len = inputStream.read(buf)) != -1) {
                        // 將照片寫入到電腦裡
                        out.write(buf, 0, len);
                    }
                    out.close();
                    inputStream.close();
                    
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    
                    client.close();
                    System.out.println(“Server: Done.”);
                    
                }
                
            }
            
        } catch (Exception e) {
            
            System.out.println(“Server: Error”);
            e.printStackTrace();
            
        }
        
    }
    public static void main(String str[]) {
        
        Thread desktopSerThread = new Thread(new JavaSocketServer());
        desktopSerThread.start();
        
    }

}



Android Client:

1. activity_main.xml:

<?xml version=”1.0″ encoding=”utf-8″?>
<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”
    xmlns:tools=”http://schemas.android.com/tools”
    android:layout_width=”match_parent”
    android:layout_height=”match_parent”
    android:paddingBottom=”@dimen/activity_vertical_margin”
    android:paddingLeft=”@dimen/activity_horizontal_margin”
    android:paddingRight=”@dimen/activity_horizontal_margin”
    android:paddingTop=”@dimen/activity_vertical_margin”
    tools:context=”com.javacourse.rongsonho.androidsocketclient.MainActivity”
    android:background=”#006699″>
    <Button
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:text=”Choose Image”
        android:id=”@+id/button”
        android:background=”#0080FF”
        android:textColor=”@android:color/white”
        android:layout_above=”@+id/button2″
        android:layout_centerHorizontal=”true” />
    <Button
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:text=”Upload”
        android:id=”@+id/button2″
        android:background=”#0080FF”
        android:textColor=”@android:color/white”
        android:layout_alignParentBottom=”true”
        android:layout_centerHorizontal=”true” />
    <TextView
            android:layout_width=”wrap_content”
            android:layout_height=”wrap_content”
            android:textSize=”25dp”
            android:id= “@+id/textView”
            android:text=”Status”
            android:textColor=”@android:color/white”
            android:scrollbars=”vertical”
            android:singleLine=”false”
            android:maxLines=”20″
            android:layout_alignParentTop=”true”
            android:layout_centerHorizontal=”true” />
    <Button
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:id=”@+id/refreshLog”
        android:text=”Refresh Log”
        android:layout_alignParentBottom=”true”
        android:layout_alignParentEnd=”true”
        android:background=”#0080FF”
        android:textColor=”@android:color/white”/>
</RelativeLayout>


2. MainActivity.java:

package com.javacourse.rongsonho.androidsocketclient;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
    Socket socket;
    //從手機裡的”我的檔案”選張照片,準備傳到電腦,
    //因不同的手機路徑可能不同,可自行修改。
    //public static final String file_name = “//storage/MicroSD/DCIM/Hello.jpg”;
    Button imageChooser, connecter, refreshLog;
    OutputStream outputstream;
    String ImagePath=””, timeString=””;
    BufferedInputStream bis;
    FileInputStream fis;
    TextView statusText;
    static byte[] mybytearray;
    int serverPort;
    InetAddress serverAddr;
    MyDBHandler dbHandler;
    SimpleDateFormat formatter;
    Date curDate;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageChooser = (Button)findViewById(R.id.button);
        connecter = (Button) findViewById(R.id.button2);
        refreshLog = (Button) findViewById(R.id.refreshLog);
        statusText = (TextView) findViewById(R.id.textView);
        statusText.setMovementMethod(ScrollingMovementMethod.getInstance());
        formatter = new SimpleDateFormat(“yyyy年MM月dd日HH:mm:ss”);
        Date curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
        String timeString = formatter.format(curDate);
        dbHandler = new MyDBHandler(this, null, null, 1);
        dbHandler.addLog(“[*]”+ timeString +”: Choose a picture to send to PCn”);
        printDatabase();
        imageChooser.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                // 建立 “選擇檔案 Action” 的 Intent
                Intent intent = new Intent(Intent.ACTION_PICK);
                // 過濾檔案格式
                intent.setType(“image/*”);
                // 建立 “檔案選擇器” 的 Intent  (第二個參數: 選擇器的標題)
                Intent destIntent = Intent.createChooser(intent, “選擇檔案”);
                // 切換到檔案選擇器 (它的處理結果, 會觸發 onActivityResult 事件)
                startActivityForResult(destIntent, 0);
            }
        });
        connecter.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Thread test = new Thread(clientSocket);
                test.start();
                //statusText.setText(statusText.getText() + “[*] Connecting to server: ” + serverAddr.toString() + “/” + serverPort + ” …n”);
                //statusText.setText(statusText.getText()+”[*] Done!”);
            }
        });
        refreshLog.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                printDatabase();
            }
        });
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);
        // 有選擇檔案
        if ( resultCode == RESULT_OK ) {
            // 取得檔案的 Uri
            if (data != null) {
                Log.e(“Socket”, “great, data is not null”);
                Uri uri = data.getData();
                if (uri != null) {
                    String path = MagicFileChooser.getAbsolutePathFromUri(this,uri);
                    ImagePath = “/”+ path;
                    Log.e(“Socket”, ImagePath);
                    curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                    timeString = formatter.format(curDate);
                    dbHandler.addLog(“[*]”+timeString+”: “+ “ImagePath: “+ ImagePath + ” n”);
                    File myFile = new File(ImagePath);
                    if (myFile.exists()) {
                        try {
                            mybytearray = new byte[(int) myFile.length()];
                            fis = new FileInputStream(myFile);
                            bis = new BufferedInputStream(fis, 8 * 1024);
                            bis.read(mybytearray, 0, mybytearray.length);
                            Log.e(“Socket”, mybytearray.toString());
                            curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                            timeString = formatter.format(curDate);
                            Log.e(“Socket”, “File read done!”);
                            dbHandler.addLog(“[*]”+timeString + “: Image has been chosenn”);
                            printDatabase();
                        } catch (IOException e) {
                            curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                            timeString = formatter.format(curDate);
                            Log.e(“Socket”, “File read error!”);
                            dbHandler.addLog(“[*]”+timeString + “: file read error!”);
                            printDatabase();
                        }
                        //輸出到電腦
                    } else {
                        curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                        timeString = formatter.format(curDate);
                        Log.e(“Socket”, “file doesn’t exist!”);
                        dbHandler.addLog(“[*]”+timeString + “: file doesn’t exist!”);
                        printDatabase();
                    }
                } else {
                    setTitle(“無效的檔案路徑 !!”);
                }
            } else {
                setTitle(“取消選擇檔案 !!”);
            }
        }
    }
    Runnable clientSocket = new Runnable() {
        @Override
        public void run() {
            try {
                serverAddr = InetAddress.getByName(“172.20.10.4”);
                serverPort = 5987;
                curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                timeString = formatter.format(curDate);
                Log.e(“Socket”, “Client: Connecting…”);
                dbHandler.addLog(“[*]”+ timeString + “: Client: Connecting…: ” + serverAddr + “/” + serverPort + “n”);
                //printDatabase();
                try {
                    socket = new Socket(serverAddr, serverPort);
                    outputstream = socket.getOutputStream();
                    outputstream.write(mybytearray, 0, mybytearray.length);
                    outputstream.flush();
                } catch (Exception e) {
                    curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                    timeString = formatter.format(curDate);
                    Log.e(“Socket”, “Client: Error”, e);
                    dbHandler.addLog(“[*]”+timeString+ “: Client: Error” + e + “n”);
                    //printDatabase();
                } finally {
                    curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                    timeString = formatter.format(curDate);
                    Log.e(“Socket”, “Transfer done!”);
                    dbHandler.addLog(“[*]”+timeString+ “: Transfer done!n”);
                    socket.close();
                }
            } catch (Exception e) {
                curDate = new Date(System.currentTimeMillis()) ; // 獲取當前時間
                timeString = formatter.format(curDate);
                Log.e(“Socket”, “Client: Error”, e);
                dbHandler.addLog(“[*]”+timeString+ “: Client: Error” + e + “n”);
                //printDatabase();
            }
        }
    };
    public void printDatabase(){
        String DBString = dbHandler.databaseToString();
        statusText.setText(DBString);
    }
}


3. MyDBHandler.java:

package com.javacourse.rongsonho.androidsocketclient;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
 * Created by RongSonHo on 5/24/16.
 */
public class MyDBHandler extends SQLiteOpenHelper {
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = “socket.db”;
    private static final String TABLE_LOG = “socket_log”;
    private static final String COLUME_ID = “_id”;
    private static final String COLUME_LOG= “socketLog”;
    public MyDBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, DATABASE_NAME, factory, DATABASE_VERSION);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        String query = “CREATE TABLE ” + TABLE_LOG + ” ( ” +
                COLUME_ID + ” INTEGER PRIMARY KEY AUTOINCREMENT, ” +
                COLUME_LOG + ” TEXT ” +
                “);”;
        db.execSQL(query);
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(“DROP TABLE IF EXISTS ” + TABLE_LOG);
        onCreate(db);
    }
    public String databaseToString(){
        String dbString = “”;
        SQLiteDatabase db = getWritableDatabase();
        String query = “SELECT * FROM ” + TABLE_LOG + ” WHERE 1″;
        Cursor cursor = db.rawQuery(query, null);
        cursor.moveToFirst();
        while(!cursor.isAfterLast()){
            if(cursor.getString(cursor.getColumnIndex(COLUME_LOG))!= null){
                dbString += cursor.getString(cursor.getColumnIndex(COLUME_LOG));
                dbString += “n”;
            }
            cursor.moveToNext();
        }
        db.close();
        return dbString;
    }
    public void addLog(String newlog){
        ContentValues values = new ContentValues();
        values.put(COLUME_LOG, newlog);
        SQLiteDatabase db = getWritableDatabase();
        db.insert(TABLE_LOG, null, values);
        db.close();
    }
    public void deleteLog(){
        SQLiteDatabase db = getWritableDatabase();
        db.execSQL(“TRUNCATE TABLE ” + TABLE_LOG +”;” );
        db.close();
    }
}

4. MagicFileChooser.java: (別人寫好的工具,取自:https://magiclen.org/android-filechooser/)

package com.javacourse.rongsonho.androidsocketclient;

/**
 * Created by RongSonHo on 6/20/16.
 */
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ClipData;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
@SuppressLint(“NewApi”)
public class MagicFileChooser {
    public static final int ACTIVITY_FILE_CHOOSER = 9973;
    private final Activity activity;
    private boolean choosing = false;
    private boolean mustCanRead;
    private File[] chosenFiles;
    public MagicFileChooser(final Activity activity) {
        this.activity = activity;
    }
    public boolean showFileChooser() {
        return showFileChooser(“*/*”);
    }
    public boolean showFileChooser(final String mimeType) {
        return showFileChooser(mimeType, null);
    }
    public boolean showFileChooser(final String mimeType, final String chooserTitle) {
        return showFileChooser(mimeType, chooserTitle, false);
    }
    public boolean showFileChooser(final String mimeType, final String chooserTitle, final boolean allowMultiple) {
        return showFileChooser(mimeType, chooserTitle, allowMultiple, false);
    }
    public boolean showFileChooser(final String mimeType, final String chooserTitle, final boolean allowMultiple, final boolean mustCanRead) {
        if (mimeType == null || choosing) {
            return false;
        }
        choosing = true;
        // 檢查是否有可用的Activity
        final PackageManager packageManager = activity.getPackageManager();
        final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType(mimeType);
        List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        if (list.size() > 0) {
            this.mustCanRead = mustCanRead;
            // 如果有可用的Activity
            Intent picker = new Intent(Intent.ACTION_GET_CONTENT);
            picker.setType(mimeType);
            picker.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple);
            picker.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
            // 使用Intent Chooser
            Intent destIntent = Intent.createChooser(picker, chooserTitle);
            activity.startActivityForResult(destIntent, ACTIVITY_FILE_CHOOSER);
            return true;
        } else {
            return false;
        }
    }
    public boolean onActivityResult(final int requestCode, final int resultCode, final Intent data) {
        if (requestCode == ACTIVITY_FILE_CHOOSER) {
            choosing = false;
            if (resultCode == Activity.RESULT_OK) {
                Uri uri = data.getData();
                if (uri != null) {
                    // 單選
                    chosenFiles = getFilesFromUris(activity, new Uri[]{uri}, mustCanRead);
                    return true;
                } else if (Build.VERSION.SDK_INT >= 16) {
                    // 複選
                    ClipData clipData = data.getClipData();
                    if (clipData != null) {
                        int count = clipData.getItemCount();
                        if (count > 0) {
                            Uri[] uris = new Uri[count];
                            for (int i = 0; i < count; i++) {
                                uris[i] = clipData.getItemAt(i).getUri();
                            }
                            chosenFiles = getFilesFromUris(activity, uris, mustCanRead);
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
    public File[] getChosenFiles() {
        return chosenFiles;
    }
    public static String[] getAbsolutePathsFromUris(final Context context, final Uri[] uris) {
        return getAbsolutePathsFromUris(context, uris, false);
    }
    public static String[] getAbsolutePathsFromUris(final Context context, final Uri[] uris, final boolean mustCanRead) {
        File[] files = getFilesFromUris(context, uris, mustCanRead);
        int filesLength = files.length;
        String[] paths = new String[filesLength];
        for (int i = 0; i < filesLength; i++) {
            paths[i] = files[i].getAbsolutePath();
        }
        return paths;
    }
    public static File[] getFilesFromUris(final Context context, final Uri[] uris) {
        return getFilesFromUris(context, uris, false);
    }
    public static File[] getFilesFromUris(final Context context, final Uri[] uris, final boolean mustCanRead) {
        ArrayList<File> fileList = new ArrayList<File>();
        int urisLength = uris.length;
        for (int i = 0; i < urisLength; i++) {
            Uri uri = uris[i];
            File file = getFileFromUri(context, uri, mustCanRead);
            if (file != null) {
                fileList.add(file);
            }
        }
        File[] files = new File[fileList.size()];
        fileList.toArray(files);
        return files;
    }
    public static String getAbsolutePathFromUri(final Context context, final Uri uri) {
        return getAbsolutePathFromUri(context, uri, false);
    }
    public static String getAbsolutePathFromUri(final Context context, final Uri uri, final boolean mustCanRead) {
        File file = getFileFromUri(context, uri, mustCanRead);
        if (file != null) {
            return file.getAbsolutePath();
        } else {
            return null;
        }
    }
    public static File getFileFromUri(final Context context, final Uri uri) {
        return getFileFromUri(context, uri, false);
    }
    @SuppressLint(“NewApi”)
    public static File getFileFromUri(final Context context, final Uri uri, final boolean mustCanRead) {
        if (uri == null) {
            return null;
        }
        // 判斷是否為Android 4.4之後的版本
        final boolean after44 = Build.VERSION.SDK_INT >= 19;
        if (after44 && DocumentsContract.isDocumentUri(context, uri)) {
            // 如果是Android 4.4之後的版本,而且屬於文件URI
            final String authority = uri.getAuthority();
            // 判斷Authority是否為本地端檔案所使用的
            if (“com.android.externalstorage.documents”.equals(authority)) {
                // 外部儲存空間
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] divide = docId.split(“:”);
                final String type = divide[0];
                if (“primary”.equals(type)) {
                    String path = Environment.getExternalStorageDirectory() + “/” + divide[1];
                    return createFileObjFromPath(path, mustCanRead);
                }
            } else if (“com.android.providers.downloads.documents”.equals(authority)) {
                // 下載目錄
                final String docId = DocumentsContract.getDocumentId(uri);
                final Uri downloadUri = ContentUris.withAppendedId(Uri.parse(“content://downloads/public_downloads”), Long.parseLong(docId));
                String path = queryAbsolutePath(context, downloadUri);
                return createFileObjFromPath(path, mustCanRead);
            } else if (“com.android.providers.media.documents”.equals(authority)) {
                // 圖片、影音檔案
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] divide = docId.split(“:”);
                final String type = divide[0];
                Uri mediaUri = null;
                if (“image”.equals(type)) {
                    mediaUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if (“video”.equals(type)) {
                    mediaUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if (“audio”.equals(type)) {
                    mediaUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                } else {
                    return null;
                }
                mediaUri = ContentUris.withAppendedId(mediaUri, Long.parseLong(divide[1]));
                String path = queryAbsolutePath(context, mediaUri);
                return createFileObjFromPath(path, mustCanRead);
            }
        } else {
            // 如果是一般的URI
            final String scheme = uri.getScheme();
            String path = null;
            if (“content”.equals(scheme)) {
                // 內容URI
                path = queryAbsolutePath(context, uri);
            } else if (“file”.equals(scheme)) {
                // 檔案URI
                path = uri.getPath();
            }
            return createFileObjFromPath(path, mustCanRead);
        }
        return null;
    }
    public static File createFileObjFromPath(final String path) {
        return createFileObjFromPath(path, false);
    }
    public static File createFileObjFromPath(final String path, final boolean mustCanRead) {
        if (path != null) {
            try {
                File file = new File(path);
                if (mustCanRead) {
                    file.setReadable(true);
                    if (!file.canRead()) {
                        return null;
                    }
                }
                return file.getAbsoluteFile();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }
    public static String queryAbsolutePath(final Context context, final Uri uri) {
        final String[] projection = {MediaStore.MediaColumns.DATA};
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(uri, projection, null, null, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
                return cursor.getString(index);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            if (cursor != null) {
                cursor.close();
            }
        }
        return null;
    }
}


參考文章:

1. Android 如何選取圖片或是檔案?:https://magiclen.org/android-filechooser/
2. 西加加 Android 手機資料傳到電腦: http://pianovv510.blogspot.tw/2013/04/android-wifi.html
3. Android TextView多行本文滾動輕鬆實現:http://sunylin.pixnet.net/blog/post/91068996-android-textview多行本文滾動輕鬆實現

sprintf in C & String.format in Java

可將字串插入可以變動的int
用for就可以產生一大批
ex. 1-01.txt, 1-02.txt, 1-03.txt ….等 很像但是有規則的字串
最常用在檔名處理上

sprintf in C:

sprintf(str, “%d”, num);
printf(“str = %sn”, str);

—————————————————————

String.format in Java:

// Store the formatted string in ‘result’
String result = String.format(“%4d”, i * j);
// Write the result to standard output
System.out.println( result );

float vs. double in Java?

public class everyday{
 
    public static void main(String[] args){
        System.out.println(“Hello Java”);
        float result=0;
        result = add(22.2,11.1);
        System.out.println(“result: “+ result);
    }
 
    public static float add(float n1, float n2){
        return (n1+n2);
    }
}

compile後,竟然跑出這樣的error message?

不太懂給一個值時,系統要怎麼判斷值為double還是float?

難道一定要hard coding把22.2和11.1強制casting到(float)嗎?