2014年8月20日 星期三

[WS2012] 關於 Windows Server 2012的一些筆記

一、Active Directory 是甚麼?(引用自Wiki)
  Active Directory是微軟 Windows Server 中,負責架構中大型網路環境的集中式目錄管理服務(Directory Services),在 Windows 2000 Server 開始內建於 Windows Server 產品中,它處理了在組織中的網路物件,物件可以是使用者,群組,電腦,網域名稱控制站,信件,設定檔,組織單元,樹系等等,只要是在 Active Directory 結構定義檔(schema)中定義的物件,就可以儲存在 Active Directory 資料檔中,並利用 Active Directory Service Interface 來存取,實際上,許多 Active Directory 的管理工具都是利用這個介面來呼叫並使用 Active Directory 的資料。


二、Directory System(目錄服務)用途?
  • 驗證
  • 查詢資訊

三、命名空間(namespace)
  • 參考DNS名稱
  • 一定要"."
  • AD的Domain名稱和註冊上可以不同(運作上絕對不會有問題)

四、在客戶端要如何知道有伺服器?

  利用DNS名稱查詢


五、為什麼單位內要有AD?(詳細內容引用自此)

1. 電腦帳號密碼集中伺服器管理,強化電腦安全性。
2. 控管所有電腦內軟體安裝。
3. 方便使用資產管理系統,減少管理時間與成本。
4. 統一由 AD 伺服器派送軟體安裝到電腦。
5. 印表機 統一由 AD 伺服器集中管理。
6. 網路磁碟機集中管理。
7. 網路分享資料夾和電腦資料夾權限控制,增加安全性。
8. 外地分公司統一連線 AD 伺服器集中管理。


六、為什麼沒有人稱為 AD Server?

  沒有 AD Server,只有 DC( Domain Controller) Server。若是稱為 AD Server,別人會以為是擁有AD功能的 Server。


七、AD的驗證過程


八、AD中的 Object是甚麼?

在AD中所有的東西都稱為物件(Object)
  • 使用者
  • 群組
  • 電腦
屬性(Attribute)
  • 欄位
  • 紀錄


九、Domain Tree
  在 AD 中會有數個網域名稱,若需要在網域名稱中共享資料或是做委派管理與組態設定時,便需要建立彼此間的組織關係,微軟將 AD 中多網域名稱相互的關係階層化,稱為網域名稱樹(domain tree),網域名稱樹結構以 DNS 識別方式來區分。


十、Trust(信任)

  AD的主要目的是為了達到 Single Sign On,而Trust是希望在多個 Domain之間作 Single Sign On。


十一、AD Forest

  AD的範圍,共用相同的Schema

WiKi解釋如下:
  在多個網域名稱的環境下,可能在不同的網域名稱之間會需要交換與共享資料,像是組態設定、使用者帳戶與群組原則設定等,在這個時候需要有一個角色來做為不同網域名稱間的資訊交換角色,同時又必須要符合 AD 樹狀結構的規範,因此微軟在多網域名稱之間建立了一個中介用的角色,稱為森林(Forest),一個組織中最多只能有一個 Forest,在 Forest 下則是各自的網域名稱樹系,而在 Forest 下的網域名稱或網域名稱樹系間,可以共享資訊。


十二、DC(網域控制站)
  • 一個Domain至少要有兩台DC。並且在AD的環境內,兩台DC都採用雙向複寫,因此經過複寫過後兩邊的結果會相同。
  • RODC(Read Only Domain Controller),採用單向複寫(例如:DC1複寫給RODC),無法對RODC作新增、刪除、修改,只負責作驗證的工作,且RODC不需要做備份。需求是給沒有IT人員的分公司,如果RODC壞掉,重灌就好。


十三、其他補充
  • 可重新啟用的ADDS:本機的DB SAM停用時,傳統的作法是重新開機然後按F8,選擇DSRM(目錄服務還原模式),然後進行維護,但因為此方法無法作遠端管理。因此從WS2008開始就新增這個功能(可重新啟用的ADDS)。
  • 資源回收桶(預設不存在):若不小心把一個物件刪掉,可以從這裡救回來。
  • WS2012 R2 分為 Standard與 datacenter(較貴,價錢差四倍)版本,兩者功能相同。兩版本差別在授權,在VM中Standard版本免費授權兩台Guest OS,而 datacenter版本 Guest OS全部免費。
  • Guest OS-指在VMware中運作的虛擬電腦作業系統,也就是經由VMware產生的虛擬作業系統。
  • AD不穩定通常都是 DNS解析有問題。AD中的電腦,DNS IP只能指向AD中的DNS Server,因為外部不知道內部的AD。客戶端查詢DNS都是使用UDP。
  • DNS 客戶端查不到的record會記得在本機的Negative Cache中,因此建議關閉Negative Cache。
  • 驗證Negative Cache是否關閉(使用cmd):
ipconfig /flushdns 清除DNS快取
ipconfig /displaydns 顯示DNS快取

  • 關閉 Negative Cache:
  1. 打開 regedit
  2. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters
  3. 新增DWORD,名稱為MaxNegativeCacheTtl,數值為0。
  4. 重啟網卡。


2014年7月28日 星期一

[Android]多選一的單選鈕 (RadioButton)

  單選按鈕即RadioButton,表示在同一群組內只能選擇一個項目。

RadioButton & RadioGroup元件
  要讓一組 RadioButton每次只能有一個被選,就必須把它們都放置在同一個 RadioGroup中。


如上圖所示,其中就有三個 RadioButton,而三個都被包在同一個 RadioGroup(你看不見)中。


getCheckedRadioButtonId():讀取單選鈕狀態
   由於 RadioButton通常是組合在 RadioGoup之下,因此在程式中要判斷使用者選擇哪一個 RadioButton,可透過 RadioGrop的 getCheckedRadioButtonId()方法,取得被選取的 RadioButton之資源 ID。接著利用判斷式(例: if/else)就可以據以決定程式的走向,其格式如下:

//取得 RadioGroup之物件
RadioGroup Iwant = (RadioGroup) findViewById(...);
    ...
//判斷選擇的項目資源 ID是不是所選擇的該項ID
if(Iwant.getCheckedRadioButtonId() == R.id.takeSword) {
    ...
}
else if(Iwant.getCheckedRadioButtonId() == R.id.cutSoul){
    ...
}
else{
    ...
}

※讀取RadioGroup的選取項目:


MainActivity.java
package tw.com.Mei_Jiang;

import android.app.Activity;
import android.os.Bundle;
import android.view.*;
import android.widget.*;

public class MainActivity extends Activity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                // Inflate the menu; this adds items to the action bar if it is present.
                getMenuInflater().inflate(R.menu.activity_main, menu);
                return true;
        }
        
        public void show(View v){
                TextView txv=(TextView)findViewById(R.id.txv);
                RadioGroup ticketType =
                                (RadioGroup) findViewById(R.id.ticketType);
                
                // 依選取項目顯示不同訊息
                switch(ticketType.getCheckedRadioButtonId()){
                case R.id.sword:        // 選 拿勝利寶劍
                        txv.setText("拿勝利寶劍");
                        break;
                case R.id.soul:        // 選 斷開魂節
                        txv.setText("斷開魂節");
                        break;
                case R.id.chain:        // 選 斷開鎖練
                        txv.setText("斷開鎖練");
                        break;
                }
        }
}

備註:別忘了,R.id.XXX都是在 R.java中以 final宣告的常數,其值是固定不變的,因此可用在 switch敘述中用來區別選取的單選鈕。


activity_main.xml
<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"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/txv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/hello_world"
        android:textSize="30sp" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/txv"
        android:layout_centerHorizontal="true"
        android:onClick="show"
        android:text="確定" />

    <RadioGroup
        android:id="@+id/ticketType"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/button1"
        android:layout_centerHorizontal="true" >

        <RadioButton
            android:id="@+id/sword"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true"
            android:text="拿勝利寶劍" />

        <RadioButton
            android:id="@+id/soul"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="斷開魂節" />

        <RadioButton
            android:id="@+id/chain"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="斷開鎖練" />
    </RadioGroup>

</RelativeLayout>

2014年7月1日 星期二

[Eclipse] 常用快速鍵 及 自動完成( Auto Complete)

一、常用鍵
  • 【Ctrl+Shift+O】:自動匯入所需要的類別
  • 【Alt + /】:程式碼提示,自動補齊 Template
  • 【Ctrl+Shift+F】:程式碼自動排版
  • 【Ctrl + F11】:快速執行程式
  • 【Ctrl+Shift+P 】:轉至匹配的括號 
  • 【Ctrl+/】:將選取的文字多行註解起來
  • 【Ctrl+D】:刪除當前這一行
  • 【Ctrl+F8】:視景切換




二、快速鍵修改處

英文版:Window->Preference->General->Keys
中文版:視窗->喜好設定->一般->按鍵

備註:快捷鍵組合可在Eclipse按下Ctrl+Shift+L來查看。



三、尋找參照

  • 【F3】:找變數宣告處
  • 【Ctrl+T】:顯示繼承樹
  • 【Ctrl+Shift+T】:快速搜尋 Class
  • 【Ctrl+滑鼠左鍵點擊】:查看使用類別的原始碼
  • 【Ctrl+L】:前往某一行




四、Debug

  • 【F11】:以除錯模式啟動 (Debug)
  • 【Ctrl + F11 】:啟動 (Run)
  • 【F5】: 步進,深入一層 (Step Into)
  • 【F6】:步進,往下一行 (Step Over)
  • 【F7】: 步進,回上一層 (Step Return)
  • 【Ctrl+.】:尋找下一個error位置
  • 【Ctrl+,】:尋找前一個error位置



五、JAVA的自動完成( Auto Complete)設定

中文版:視窗 --> 喜好設定 --> Java --> 編輯器 --> 內容輔助 --> Auto Activation




英文版:Window--> Preferences --> Java --> Editor --> Content Assist --> Auto Activation




六、XML的自動完成(Auto Complete)設定

中文版:視窗 --> 喜好設定 --> XML --> XML Files --> 編輯器 --> 內容輔助 --> Auto Activation



英文版:Window --> Preferences --> XML --> XML Files --> Editor --> Content Assist --> Auto Activation



Reference

2014年6月27日 星期五

[Android]使用 BaseAdapter客製化 ListView


上一篇:[Android] Action Bar Tabs 和 ListView 簡易示範

範例下載:GitHub

  上一篇已經有提到如何簡單使用 ListView的功能,今天我們就來使用 BaseAdapter客製化 ListView (把每一個 ListView都用 Layout顯示)。


一、為了程式的可維護性及 Android的 MVC架構,使 Controller及 Model分開,我們將新增一個套件( package),並且在裡面建立 ListView Adpater及 項目要用的物件。

  對著 src按右鍵,並且選擇新建-->套件 我們在這邊取名為"com.example.utils",接著在此套件中新建兩個類別( class),分別取名為 NewItem及 ListViewAdpater,完成後如下圖:


  

然後先撰寫 NewItem物件的內容:

package com.example.utils;

public class NewItem {
 
 private String Memo;
 private String Time;
 
 public NewItem(String memo,String time) {
  this.Memo=memo;
  this.Time = time;
 }
 
 public String getMemo(){
  return Memo;
 }
 
 public String getTime(){
  return Time;
 }
 
 
}

二、創立顯示 Item的 Layout



這邊命名為fragment0_listitem.xml,內容如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <!-- first row that Country and publish date -->

    <TextView
        android:id="@+id/Time"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="right|center_vertical"
        android:maxLines="1"
        android:text="2014-03-10"
        android:textColor="#0f55bd"
        android:textSize="15dp" />

    <TextView
        android:id="@+id/Memo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ellipsize="end"
        android:maxLines="2"
        android:text="item 1"
        android:textColor="#000000"
        android:textSize="20dp" />

</LinearLayout>



三、實作 ListViewAdpater(繼承  BaseAdapter)的內容。 
 
  這邊簡單介紹一下 BaseAdapter(網路上有人翻作基礎連接器)。上一章有說到 Adpater是用來給像是 Spinner、ListView、GridView塞入資料用的,而這三個其實都有各自的 Adapter,但  BaseAdapter對這三個是可以通用的,這是為什麼呢?由 API可知, 這是因為 BaseAdapter實作了 ListAdapter和 SpinnerAdapter,而 GridView 的 Adpater本身也實作了 ListAdapter,因此 BaseAdapter對它們來說是三者通用的。



ListViewAdpater.java內容如下:

package com.example.utils;

import com.example.actionbartabstest.R;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class ListViewAdpater extends BaseAdapter {
 Context context;
 List items;

 public ListViewAdpater(Context context, List items) {
  this.context = context;
  this.items = items;
 }

 //hold views for costomized listview
 private class ViewHolder {
  TextView txtMemo;
  TextView txtTime;
 }

 @Override
 //How many items are in the data set represented by this Adapter.
 public int getCount() {
  return items.size();
 }

 @Override
 //Get the data item associated with the specified position in the data set.
 public Object getItem(int position) {
  return items.get(position);
 }

 @Override
 //Get the row id associated with the specified position in the list.
 public long getItemId(int position) {
  return position;
 }

 @Override
 //Get a View that displays the data at the specified position in the data set.
 public View getView(int position, View convertView, ViewGroup parent) {
  ViewHolder holder;
  LayoutInflater mInflater = (LayoutInflater) context
    .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
  if (convertView == null) {
   convertView = mInflater.inflate(R.layout.fragment0_listitem, null);
   holder = new ViewHolder();
   holder.txtMemo = (TextView) convertView.findViewById(R.id.Memo);
   holder.txtTime = (TextView) convertView.findViewById(R.id.Time);
   
   convertView.setTag(holder);
  } else {
   holder = (ViewHolder) convertView.getTag();
  }

  NewItem items = (NewItem) getItem(position);
  
  holder.txtMemo.setText(items.getMemo());
  holder.txtTime.setText(items.getTime());
  
  return convertView;
 }

}

其函數作用內容可以參考API:BaseAdapterAdapter



四、將其加入 我們先前準備的 MainActivity中。

  在前一篇我們已經產生了一個 Fragment來塞入 ListView,在這邊我們要來取代原本的內容。請將 Fragment0的 onCreateView改寫如下:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
        List rowitem= new ArrayList();   
        View rootView = inflater.inflate(R.layout.fragment0, container, false);
   
        rowitem.add(new NewItem("item 1","2014/06/26"));
        ListViewAdpater adpater= new ListViewAdpater(getActivity(),rowitem);
        listView.setAdapter(adpater);
   
        return rootView;
}
}


五、Demo


~今天就講解到這裡~

2014年6月24日 星期二

[Android] Action Bar Tabs 和 ListView簡易示範


範例下載:GitHub

  相信大家對 Twitter和 Facebook這種 View應該都不陌生吧!拜諸多大神所賜,現在要寫出這種 View已經是非常容易的事情。今天我們就來簡單實作這種 View─ Action Bar Tabs,並且加入幾個 UI及示範 ListView。



一、首先要創立專案,這裡要特別注意的是在最低版本中需要選擇 API 11(Android 3.0)以上。



  接著就一直下一步,直到 Create Activity的地方選擇 Blank Activity,然後下一步。接著在 Blank Activity的 Navigation Type中選擇 Action Bar Tabs (with ViewPager)這個選項,然後「完成」。



接著我們就直接來 Demo一下剛產生的專案:


接著就可以試著左右滑動,看一下這三個 View,是不是很快呢?


二、接著我們稍微改一下這個專案,將 3個 Fragment改成兩個 Fragment,並且分別在兩個 View中加入不同的元素

改成兩個 Fragment其實也很簡單,只要更改 getCount函數中的回傳值就可以了。
@Override
public int getCount() {
    return 2;
}

  接著為了要方便管理兩個 Fragment,我們將直接修改 PlaceholderFragment這個函數以達到我們的需求:
public static class Fragment0 extends Fragment {

    private static final String ARG_SECTION_NUMBER = "section_number";

        public static Fragment0 newInstance(int sectionNumber) {
            Fragment0 fragment = new Fragment0();
            Bundle args = new Bundle();
            args.putInt(ARG_SECTION_NUMBER, sectionNumber);
            fragment.setArguments(args);
            return fragment;
        }

        public Fragment0() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            TextView textView = (TextView) rootView.findViewById(R.id.section_label);
            textView.setText(Integer.toString(getArguments().getInt(
                ARG_SECTION_NUMBER)));
            return rootView;
        }
}

  然後依樣畫葫蘆,創造出另一個 Fragment1。也由於我們要分開控制兩個 Fragment,所以也要為它們各自產生 layout,我們可以選擇直接更改 fragment_main.xml成 fragment0.xml,並且複製一份成為 fragment1.xml:



  由於 layout改變了,所以我們必須回去修改 MainActivity的 getItem函數,讓它分別對照到兩個 layout:

@Override
public Fragment getItem(int position) {
    switch(position){
        case 0:
        return Fragment0.newInstance(0);
        case 1:
        return Fragment1.newInstance(1);
        default:
        return Fragment0.newInstance(0);   
    }
}

備註:getItem函數可以回傳拿到上面第幾個 Fragment的實體。

這時候我們在第二個 Fragment加入一個 EditText和一個 Button。

Demo一下改完後的狀況:



三、接下來我們要在第一個 Fragment加入 ListView,並且簡單示範一下。

關於ListView:
  ListView是在 Android中很常見的一種 UI,與 iOS的 Table View雷同, ListView 通常使用在需在同一畫面大量使用時,如:電話簿、檔案管理、條列資訊....,都很建議使用。而 ListView在使用上需要搭配 Adapter用以連接資料。

不多說,先在 fragment0.xml加入ListView:
<ListView
    android:id="@+id/listView1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true" >
</ListView>

然後我們修改 Fragment1的 onCreateView:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment0, container, false);
    ListView listView=(ListView) rootView.findViewById(R.id.listView1);
    String[] testArryStrings = new String[]{"1", "2", "3", "4", "5"};
    ArrayAdapter aa= new ArrayAdapter(getActivity(),
        android.R.layout.simple_expandable_list_item_1,
        testArryStrings);
    listView.setAdapter(aa);
    return rootView;
}

關於ArrayAdapter:
  ArrayAdapter是 Android中的一個 Adapter,它可以連結字串陣列到單一個 Text View的 List物件當中。上方程式碼有幾個重點:

  • ArrayAdapte所接收之項目為 Array。
  • ArrayAdapte的方法裡面並沒有提供多欄位的顯示方式。
  • 第一個參數代表目標為 Fragment1的 Activity。
  • 在第二個參數中使用 "android.R.layout.simple_expandable_list_item_1",表示是用 Android 內建的配置。
  • 最後一個參數是欲顯示的項目(字串陣列)。


Demo一下:




~今天就講解到這裡~


Reference 

2014年6月23日 星期一

[jQuery] jQuery入門


  jQuery是一套 JavaScript的函示庫,其主要特色是有著強大的選擇器、跨瀏覽器、Ajax(非同步的 JavaScript 與 XML 技術)、事件等。也因為是 JavaScript的函示庫,所以若要學會使用 jQuery必須要有一點 JavaScript的基礎,在接下來的教學中會簡單介紹放置位置、import、selector、modify、action、ajax等項目。

一、寫在哪?
  由於它是一套 JavaScript的函示庫,所以放置的地點跟 JavaScript是一樣的,需要放在SCRIPT標籤內。

<script>…</script>

二、匯入(import)
  你可以透過官網下載其檔案並進行匯入,或者直接填入官網的檔案位置,其語法如下:

<script src="https://code.jquery.com/jquery-2.1.1.js"></script>

  但是一般為了避免因官方出問題或者你想離線時寫 jQuery,一般建議將它下載下來以方便使用。

官方連結:點我



三、錢字號(Dollar sign)的意義
$代表的就是 jQuery的意思,因此若你在寫作中把 $換成 jQuery也是相通的(Q要大寫)。以下這兩種寫方是一樣的:

$(document).ready(function(){...});
jQuery(document).ready(function()...});


四、甚麼時候開始執行?
  有三種開始情況:
  • body:在讀取完 body標籤後開始執行。
  • document:在讀取完所有文件(.css、.js、.html)後開始執行。一般情況下都是使用這種。
  • window:當所有畫面都載入完畢後開始執行。若你希望文字內容優先載入,圖片晚一點在載入可以使用這種。


寫法如下:

$(document).ready(function(){ });

接下來我們展示第一個範例:
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.1.js"></script>
<script type="text/javascript">
    var pageOnLoad = function pageOnLoad() {
  alert("Hello World")
 }
 $(document).ready(pageOnLoad);!
</script>
</head><body></body>
</html>

若成功了,會在讀入畫面後立即跳出一個彈跳視窗:

五、選擇器(selector)
  一般會用的有三種,我們也使用範例來了解:

$("body").html(); //選取 body標籤內的所有內容
$("#id_name").html(); //"#" 選取 id名稱為 id_name的所有內容
$(".class_name").html(); //"." 選取 class名稱為class_name的所有內容。

  為什麼'上述都要強調所有呢?因為選擇器所選到的,其實都是陣列型態。所以取到的物件都可以加上陣列索引,若沒加的話預設就是 0開始。

var jsObj = $(".class")[0];

範例如下:
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.1.js"></script>
<script type="text/javascript">
 var pageOnLoad = function pageOnLoad() {
  alert($("body").html());
  alert($(".title").html());
  alert($("#subtitle").html());
 }
 $(document).ready(pageOnLoad);
</script>
</head>
<body>
 <h1 class="title">Title</h1>
 <h2 id="subtitle">subtitle</h2>
</body>
</html>



六、修飾(modify)

 $(".class").append('…');//在所匹配的元素內加入內容
 $(".class").before('…');//在所匹配的元素之後加入內容
 $(".class").after('…'); //在所匹配的元素之前加入內容


七、動作(action)

$(".class").click(); 
$(".class").onclick(function() {…}); //按一下並觸發function()內的事件
//下列兩種要 jQuery 1.7版後才能使用
$(".class").on("click", function() {…}); //按一下並觸發function()內的事件
$(".class").on("click", "sel", function() {…}) //按一下觸發function()內的事件,並且將sel(自訂的)事件繼承給它


八、Ajax (按我看wiki簡介)
  這邊要注意一下,由於一般可能會預設不同意不同網域載入(不是所有瀏覽器都有此問題,例如IE8則沒此限制),因此會產生 Access-Control-Allow-Origin' header 的問題,解決方法是在提供 Ajax 服務的 response 加上 header (Access-Control-Allow-Origin:*) 即可,但若只是想單純測試,Chrome瀏覽器可以使用 Allow-Control-Allow-Origin套件(按我進入下載安裝頁面)。安裝完後,Chrome瀏覽器右上方會出現CORS按鈕,綠色代表已啟動,紅色則反之。


使用 webservice取得資料,其範例如下:
$.ajax({
    type: "POST", //使用POST方式
    url: "填入webservice網址",
    dataType: 'text', 
    data: {input:"若需要輸入甚麼,可以寫在這裡"},
    success: function(data){ //成功取得資料時
        alert(data);
        var result = jQuery.parseJSON(data); //取回資料後轉換成 JSON格式
    },
    error: function() { //發生錯誤時
        alert(“無法連線至伺服器");
    }
});

上述寫法沒有順序性,並且可依照需求填寫。


OK,今天就簡單介紹到這裡吧~

2014年6月20日 星期五

[Android]監聽事件之順序關係

   在 Android 中,onClick、onLongClick 的觸發是和 ACTION_DOWN 及 ACTION_UP 相關的,在時序上,如果我們在一個 View 中同時覆寫了onClick、onLongClick 及 onTouchEvent 的話,onTouchEvent 是最先捕捉到 ACTION_DOWN 和 ACTION_UP 事件的,其次才可能觸發 onClick 或者onLongClick。

※下面的 Log 是在 onLongClick() 方法 return false 的情況下,一次觸碰操作的基本時序:
06-19 11:05:15.023: DEBUG/TestActivity(277): onTouch ACTION_DOWN
06-19 11:05:15.533: DEBUG/TestActivity(277): onLongClick
06-19 11:05:16.603: DEBUG/TestActivity(277): onTouch ACTION_UP
06-19 11:05:16.663: DEBUG/TestActivity(277): onClick
可以看到,在 ACTION_UP 後仍然觸發了 onClick() 方法。

[JAVA]extends VS implements

  由於 JAVA 不像 C 可以多重繼承,但是我們可以利用 interface 來實現。綜合以上所述, 可列出以下幾點特徵:

  • 具有 abstract method 的 class 必須宣告為 abstract class。
  • 繼承 abstract class 的子類別必須 override 所有父類別的 abstract method, 否則子類別也必須宣告為 abstract class。
  • 實作 Interface A 的 Class 必須實作 A 裡的所有 method, 否則必須宣告自己為 abstract class。
  • 不能直接 new abstract class, 只能 new 其非 abstract class 的子類別。


PS:extends必須在implements前面

不懂嗎? 呂布只有一個親爸爸(繼承),但他有好多個乾爸爸(實作)~~~~

[Objective-C]初學入門,以 Fraction為例


相關資訊:
Xcode版本:5.1.1
範例下載:GitHub

         歡迎加入 Objective-C的世界,此教學筆記將以實作分數為例簡單介紹這個語言。首先你必須先安裝好 Xcode,並且對 C語言有著基本的認識。接著,我們就開始一步步建置這個專案:

一、首先打開 Xcode,並從左上角的 File-->New-->Project新增一個專案。



二、由於我們並不是要寫 iOS的 App,所以從左下角的 OS X的類別選擇 Application,接著在右邊選擇 Command Line Tool (用命令提示字元來執行),然後 Next。


三、接著依照提示填上相關的專案名稱, Type選擇 Foundation。



四、Next之後你就可以選擇專案的儲存位置,以及下方問你有無需要作 Source Control, Source Control基本上是用來做版本控制的功能,由於我這邊並不需要,所以無需打勾。


五、Create後,就已經看到 Xcode幫我們產生的主程式以及相關的目錄。



六、按左上角的 Play按鈕,就可以在左下角見到預設產生的"Hello World"囉!這行訊息是使用 NSLog印出的,NSLog是 Objective-C用來在命令列印出訊息的函數,其中是以 NSString作為參數,若你想用 C語言的 printf也是可以的,但 NSLog預設提的格式訊息(如時間)是非常方便的,因此這邊均會使用 NSLog來印出訊息。



七、接著就要來實作 Fraction,直接對左邊的 testFraction目錄在觸控板上雙指按下(或點右鍵),選擇 New File。


八、選擇 OS X的 Cocoa --> Objective-C Class,然後 Next。



九、Class名稱我們這邊取名為 Fraction,Subclass of選擇 NSObject。NSObject是 Objective-C 的抽象根類別,幾乎所有的物件都繼承自它, NSObject可以幫你的物件初始化,並且真正實作它。



十、接下來你就可以看到它幫我們產生的兩個檔案 .h跟 .m檔。
  • .h 為標頭檔,所有要在外部使用的屬性及方法都要在這裡做宣告。
  • .m 為 Objective-C 的主檔,所有的屬性設定及方法都寫在這裡。





十一、接著我們直接看要寫的程式碼吧!

  • Fraction.h 在這裡我們要宣告外在類別可宣告外在可用的屬性(變數)與方法,若沒在此宣告,外在是無法順利呼叫的。

#import <foundation oundation.h="">

@interface Fraction : NSObject
//自行宣告屬性
@property (nonatomic)int numerator, denominator;
//宣告為property的主要功能是方便我們取用或設定物件裡的資料成員,會自動生成get, set方法
//nonatomic-->允許被不同執行緒同時存取,相對於atomic,速度較快,但較不安全
@property (nonatomic) NSString *str;

//手動實作 get、set方法
-(void) setTo:(int)n over:(int)d;
-(void) print;
-(Fraction*) add:(Fraction*) f;
-(Fraction*) Subtract:(Fraction*) f;
-(Fraction*) Multiply:(Fraction*) f;
-(Fraction*) Divide:(Fraction*) f;
-(Fraction*) Reduction:(Fraction*) f;
@end


  • Fraction.m

#import "Fraction.h"

@implementation Fraction
-(NSString*)description 
{
    //回傳一個NSString結果的分數
    return [NSString stringWithFormat:@"%d/%d",self.numerator,self.denominator];
}

-(NSString*) str
{
   //避免產生空物件
    if(!_str)
    {
        _str=[NSString new ];
    }
    return _str;
}

//覆寫Denominator的set方法,避免Denominator為0
-(void)setDenominator:(int)denominator 
{
    if(denominator) _denominator=denominator;
}

//設定分數之分子分母
-(void) setTo:(int)n over:(int)d 
{
    //兩種寫法均可行
    [self setNumerator:n];
    self.denominator=d;
}

-(void) print
{
    NSLog(@"%i / %i",self.numerator,self.denominator);
}

-(Fraction*) add:(Fraction*) f
{
    Fraction *sum=[Fraction new];
    sum.denominator = self.denominator * f.denominator;
    sum.numerator = self.numerator * f.denominator + self.denominator * f.numerator;
    sum=[sum Reduction:sum];
    return sum;
}

-(Fraction*) Subtract:(Fraction*) f
{
    Fraction *sub=[Fraction new];
    sub.denominator = self.denominator * f.denominator;
    sub.numerator = self.numerator * f.denominator - self.denominator * f.numerator;
    sub=[sub Reduction:sub];
    return sub;
}

-(Fraction*) Multiply:(Fraction*) f
{
    Fraction *mul=[Fraction new];
    mul.denominator = self.denominator * f.denominator;
    mul.numerator = self.numerator * f.numerator;
    mul=[mul Reduction:mul];
    return mul;
}

-(Fraction*) Divide:(Fraction*) f
{
    Fraction *div=[Fraction new];
    div.denominator = self.denominator * f.numerator;
    div.numerator = self.numerator * f.denominator;
    div=[div Reduction:div];
    return div;
}

-(Fraction*) Reduction:(Fraction*) f
{
    for (int i=2; i<f.denominator; i++) {
        while ((f.numerator%i==0) && (f.denominator%i==0)) {
            f.numerator = f.numerator / i;
            f.denominator = f.denominator / i;
        }
    }
    return f;
}



  • main.m 程式進入點,從這裡對 Fraction類別進行測試

#import <Foundation/Foundation.h>
//外部的 import是使用 ” 符號
#import "Fraction.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        Fraction *myFrac1;
        //myFrac1 = [Fraction alloc];
        //myFrac1 = [myFrac1 init];
        myFrac1 = [[Fraction alloc] init];
        [myFrac1 setTo:2 over:3];
        [myFrac1 print];
        
        Fraction *myFrac2 = [Fraction new];
        [myFrac2 setTo:1 over:3];
        //覆寫set的方法 使得此變數不得為0
        [myFrac2 setDenominator:0];
        [myFrac2 print];
        Fraction *myFrac3;
        myFrac3 = [myFrac1 add:myFrac2];//加
        [myFrac3 print];
        myFrac3 = [myFrac1 Subtract:myFrac2];//減
        [myFrac3 print];
        myFrac3 = [myFrac1 Multiply:myFrac2];//乘
        [myFrac3 print];
        myFrac3 = [myFrac1 Divide:myFrac2];//除
        [myFrac3 print];
        
    }
    return 0;

}

十二、Demo

2014年6月19日 星期四

[Android]監聽 長按 事件

  先前介紹的OnClick()不須傳回任何值,但onLongClick() 必須一個布林值,表示是否引發「長按」事件,還是也要在之後手指放開時引發「按一下」事件。這是因為「長按」一定是包含在「按一下」的過程中,因此必須依靠傳回值,來告訴系統只要引發「長按」就好。

  一個用戶的操作會被傳遞到不同的前端物件的不同監聽方法處理,任何一個接收並處理了該次事件的方法如果在處理完後返回了 true,那麼該次 event 就算被完全處理了,其他的 View 或者監聽方法就不會再有機會處理該 event 了。


接續上一篇的內容:按一下 的事件處理範例

※下面得範例將要在長按按鈕後,將計數值歸0: MainActivity.java
package tw.mangolai.counter2;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
//匯入監聽器介面
import android.view.View.OnClickListener; 
//匯入監聽器介面
import android.view.View.OnLongClickListener; 
import android.widget.Button;
import android.widget.TextView;

//實作 OnLongClickListener介面
public class MainActivity extends Activity implements OnClickListener, OnLongClickListener { 
    TextView txv;  //用來參照 textView1 元件的變數
    Button btn;   //用來參照 button1 元件的變數
    int counter = 0; //用來儲存計數的值, 初值為 0

    @Override
    //實作監聽器介面中定義的 onClick方法
    public void onClick(View v) { // 實作監聽器介面中定義的 onClick方法
        // 將計數值加 1, 然後轉成字串顯示出來
        txv.setText(String.valueOf(++counter)+"顆鑽石"); 
    }

    @Override
    //實作長按 (OnLongClickListener 介面)的方法
    public boolean onLongClick(View v) { 
        counter = 0;
        txv.setText("0"+"顆鑽石");
        return true;
    }
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //找出要參照的物件
        txv = (TextView) findViewById(R.id.textView1); 
        //找出要參照的物件
        btn = (Button) findViewById(R.id.button1); 
        //登錄監聽物件, this表示活動物件本身
        btn.setOnClickListener(this); 
        //將活動物件登錄為按鈕的長按監聽器 
        btn.setOnLongClickListener(this); 
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

[Android]按一下 的事件處理範例


 ※下面的範例是每按一下按鈕,就讓計數器加1:
activity_main.xml
<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"
    tools:context=".MainActivity" >
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="42dp"
        android:text="我就再回去看"
        android:textSize="60dp" />
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="40dp"
        android:text="0顆鑽石"
        android:textSize="60dp" />
</RelativeLayout>

MainActivity.java
package tw.mangolai.counter;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
// 匯入監聽器介面
import android.view.View.OnClickListener; 
import android.widget.Button;
import android.widget.TextView;
// 實作 OnClickListener 介面
public class MainActivity extends Activity implements OnClickListener { 
    // 用來參照 textView1 元件的變數
    TextView txv;  
    // 用來參照 button1 元件的變數
    Button btn;   
    // 用來儲存計數的值, 初值為 0
    int counter = 0; 

    @Override
    // 實作監聽器介面中定義的 onClick 方法
    public void onClick(View v) { 
        // 將計數值加 1, 然後轉成字串顯示出來
        txv.setText(String.valueOf(++counter)+"顆鑽石"); 
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 找出要參照的物件
        txv = (TextView) findViewById(R.id.textView1); 
        // 找出要參照的物件
        btn = (Button) findViewById(R.id.button1); 
        // 登錄監聽物件, this 表示活動物件本身
        btn.setOnClickListener(this); 
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

[Android]事件處理


事件處理的機制

   當使用者對手機進行各種操作時,即會產生對應的事件(Event),例如按下按鈕時,會產生對應的 OnClick事件。
   若要處理任何事件,必須準備一個能處理事件的監聽物件(或稱監聽器,Listener),然後將之登錄到來源物件中,那麼當來源物件有事件發生時,就會自動呼叫相對應的監聽事件來進行處理。

 不懂嗎? 為了抓小偷,所以我們在家中裝了監視器,若沒有監視器監看,那就 沒~有~畫~面~



JAVA 的介面(Interface)


   在 Android中,是以 JAVA的介面(Interface)來規範事件處理的方法,簡單說就是凡是要成為某類事件的監聽物件時,就要需要提供符合其介面規定格式的方法。例:按一下(OnClick)的事件,對應規範就是OnClickListener界面,該介面必須要規定了監聽物件提供的 onClick() 方法的規格,我們必須要專寫 onClick() 的方法才能處理「按一下」的事件。

注意:這裡稱的面(Interface)跟使用者介面(User Interface)是不同的唷~~~


※下面的範例將介紹實作介面以及監聽器使用方法:

//這就是實作 監聽器Listener 唷~~~~~~
class MyOnClickListener implements OnClickListener{ 
    //這裡撰寫監聽物件的處理方法,就是按下按鈕後要做啥~
    public void onClick(View v){ 
        switch(v.getId()){
        //按鈕1 要做啥~
        case R.id.btn1: 
            textView1.setText("textview1");
            break;
        //按鈕2 要做啥~
        case R.id.btn2: 
            textView2.setText("textview2");
            break;
        }
    }
}
private MyOnClickListener myOnClickListener = new MyOnClickListener();

//登錄就是下面這兩行啦~~~~~
//this代表 目前的物件,也就是勿前執行的方法所屬的物件 
button1.setOnClickListener(this); 
//這裡寫myOnClickListener馬耶通~~~
button2.setOnClickListener(myOnClickListener); 
/*
為何這樣寫?
因為在同一個類別內無法實作同一個方法兩次唷~~~~~~
物件都可以用陣列的方式來達到大量控制唷~~~~~~
*/

實作 (Implement) 介面其實只是一種宣告而已,真正要做得是:

  1. 撰寫符合該介面的規格 (方法名稱、參數、傳回值)的方法(method) 
  2. 向來源物件登錄自己成為該事件的監聽物件


 不懂嗎? 人類想要看的見,上帝必須要實作"眼睛"。上帝忘記實作時,你就會看不見五顆鑽石!!!!!