2016年1月17日 星期日

C++  筆記

#include格式
1. include <fileName> : 叫前置處理器到系統的include資料夾去找此檔案。主要用於標準函式庫中的檔案。
2. include "fileName" :先去目前工作目錄下找,找不到再到系統的include資料夾去找。此使用方式常用於我們自己寫的檔案。


const V.S #define
1.const: constant variable, 一開始宣告時, 便一定要定義它的值, 一旦定義完後, 便無法改變此變數的值。就像java中的final關鍵字。
2.#define:replacing text macros, 巨集命令, 通常定義在程式的一開頭, 且都是使用大寫。
ex: #define PI 3.14
Preprocessor執行程式前會先將使用define變數的變數名稱替換成常數值後, 才開始編譯。
Preprocessor並不懂c++語法,所以在做macros時, 不會做型別與語法的檢查。而const會。

inline
inline適合用在內容很少的函式,
ex:
inline giveme(){
    a+a;
}
你在使用的時候,呼叫到inline的函式,
編譯器會自動幫你替代成函式中的內容,
不過編譯器會看狀況要不要替代。
result = giveme();
==>result = a+a;

優點:
因為是將function替代掉, 直接執行
比一般呼叫函式速度快,執行流程不會跳來跳去, 一般呼叫函式會切換,所以執行慢。
 但是缺點也是你的程式檔案內容會長大


typedef
1. 用typedef可以為已經存在的型別另外建立新的名稱。
typedef 型別  新的名稱;
ex: typedef unsigned char abc;

Postfix increment Operator V.S Prefix increment Operator
1. Postfix increment Operator: 後置遞增運算子, i++
2. Prefix increment Operator, 前置遞增運算子, ++i
ex:
int i =5;
int j = (i++)+5
==> i = 6, j = 10

ex:
int i =5;
int j = (i++)+i+(i++);
==> i=7, j = 17

ex:
int i=5;
int j = (--i)+i+(--i)
==> i = 3, j = 11

<<,>>
1. 用乘除法(*或/)是很耗CPU時間, 所以我們可以利用<< , >>來做乘除運算,藉此加快速度。
<< n 等於 數字乘上2^n
>> n 等於 數字除上2^n

參數中的預設值
這大概是我寫c++時最喜歡它的地方,
void getme(int a,b=3);
當caller call getme()只有給a的值, 沒給b的值時,
==> getme(15);
getme()會自動幫你把b值填上, 這個b =3。
但是預設值只能從最右邊的值開始設喔!
也就是你不能寫  getme(int a=3, b)
一定要b有預設值, a才可以設定預設值


local variable V.S static variable
1. local variable (在函數中的變數)會被放在stack中, 當函式消失, stack也會不見
2. static variable 不會放在函數stack中, 會在程式一執行時便存在於記憶體中
當local variable和Global variable有重複名稱時,
會以local variable為主, 如果在函數中想要存取同名稱的global variable,
就使用 :: 。
ex:   ::x
就會存取到global 的x

指標與陣列
指標是用來存放位址的(通常4 bytes),來看下面的例子
Ex:
int j =9;
int *i = &j;  // 把j的位置給i
==> i = j的位置,  *i = 9;   // * 是提取值的意思

可以看成 (int*) i=&j;
用這個方式來記會比較好。

因為在宣告型態之後的寫法,
是這樣寫的:
i = &j;
*i = j;
如果你是用第一種方法 int *i = &j; 來記一定會混淆。

另外指標的*與陣列的[]可以互用:
int a[] = {7,8,9};
int *i = a;
==> *i = 7, *(i+1) = 8, i = a陣列的位置
==> i[0] =7
==>*a = 7, *(a+1) =8

另外來談談直接new一塊記憶體
一開始宣告就配置記憶體
int *a=new int(10);

釋放記憶體
delete a;

需要的時候再配置記憶體
int *a;
...
...
a = new int(10);
或 a= new int;

配置陣列的空間
int *parray = new int[9];
..
delete [] parray;

⦿ 陣列變數不能指定給另一個陣列變數, 通常會使用指標來指定,
不用指標的方式就是要用迴圈一個一個複製。
ex:
int a[]={1,2} 或 int a[5] = {1,2}
int b[] = a[];  // 錯誤!


Reference Type
Reference Type是建立variable的別名, 把它想做是你的綽號,
你的名字叫做王大明, 朋友叫你小明, 你媽叫你阿明。
王大明,小明跟阿明都是叫你的意思,對吧!
Reference Type就是取綽號的意思。
這裏有個很重要的事情, 就是宣告的時候,
必須一定要初始化。

Ex:
int i=1;
int &j=i;  // j就是你的綽號, 在這邊一定要給值,讓它初始化
==> i =1, j=1

改變i的值,會連j 也一起改, 因為他們兩個是指向同一塊記憶體
i = 99;
==> i =99, j=99

Reference Type 常用在function的參數傳遞跟回傳值上。


呼叫函式的方法
呼叫函式的方式有三種:
1. call by value : 把參數數值複製過去,  所以被呼叫的函式中的參數與呼叫時的參數是不同的。
2. call by address : 函數的參數型別是指標, 呼叫時是把address丟給函式
3. call by reference : 函數的參數型別是reference type, 函式中用的是綽號。
call by address 和call by reference其實是一樣的,
都是指向同一個記憶體。
至於要選擇哪個用呢?
call by reference前面有說,宣告時一定要初始化。
至於call by address並沒有這樣規定。
因此, call by reference時, 丟過來的參數一定要是已存在變數或物件,
而call by address你甚至可以丟個null pointer過來。



ex:
Call by Address
void giveme(int *i);

....
int x;
giveme(&x);
把它想像成 int* i= &x;

陣列也是一種指標
void giveme(int array[]);

....
int originalArray[10];
giveme(originalArray);

c++陣列沒有可以得知陣列size的function,
所以在傳的時候會順便把size傳過去
ex: void giveme(int array[], int size);

Call by reference

void giveme(&x);

....
int i =9;
giveme(i);
把它想成 &x = i;


Return value
1. return pointer
2. return reference

ex:
int *funtion(int *p){
return p;   // return pointer
}

int &function(int *p){
int i=100;
return *p;
或return i;
}


public, protected, private

// struct 成員預設都是public, from C
struct Sky{
    int a=0;

private:  //以下才是private
    int b;
}

// class 成員預設都是private
class Sky{
    int a =0;

public:  //以下才是public
    int b;
}


“. ” v.s "->"
呼叫function的時候, 有兩種方式, “. ” v.s "->"
很常有人搞不清楚, 這是很基本的喔~
得要好好釐清才行:
物件.function / 物件.variable
pointer -> function

前者是物件呼叫函式的方式,
使用物件來呼叫函式就要用 ". "
如果你是指標的話那就使用 -> 來呼叫函式/variable。



Class
定義在類別中的funtion有個特性:預設是inline funtion(for all?)。
宣告方式除了在class中直接宣告並定義,
另一種:
class Sky{
void int method();
}

void Sky::method(){
....
}

static
class Sky{
static int b=99;
static int a;
}
int Sky::a=19;

static function
class Sky{
static getRain()...
}

使用的時候:
Sky::getRain();

new class方式:
Sky mySky;
Sky *sky = new Sky;

sky = &mySky;  // ok
*sky = mySky;  // not ok

2015年11月27日 星期五

Android: Install apk with INSTALL_FAILED_DEXOPT error

I want to install the Camera2 apk which is compiled by myself from AOSP.
However, I come across the error message: INSTALL_FAILED_DEXOPT

Because the my target device has Camera2.apk from GMS.
Without uninstall the Camera2.apk from device,
just push the Camera2.apk you compiled to the device.
1. adb push Camera2.apk system/app/Camera2
2. adb push Camera2.odex.gz system/app/Camera2/x86_64

===========================================
想要build aosp的Camera2
build完後想安裝到device上卻出現
INSTALL_FAILED_DEXOPT  error

主要是devices上已經有Camera2的apk了,

(gms上的Camera叫GoogleCamera)


解決方式:
不砍system/app底下的Camera2 folder,
直接push即可。

1. adb push Camera2.apk system/app/Camera2
2. adb push Camera2.odex.gz system/app/Camera2/x86_64

2015年11月25日 星期三

Android : Handler dind't execute runnable.

When I use handler to execute a runnable, I found sometimes process doesn't execute this runnable.
Why?

Let's describe it in detail.

Situation:
I use ui handler to execute a runnable. Also, this ui handler execute and remove some message tasks.
However, sometimes the runnable doesn't be executed.

How come?
Because this ui handler remove the message which message.what is 0, 
and handler will remove all the messages which message.what is 0.
The runnable also be removed from the message queue.

For example:

 int UPDATE_PIC = 0;  
 ......  
 Message msg = new Message();  
 msg.what = UPDATE_PIC ;  
 .....  
 Handler.sendMessage(msg);  
 Handler.post(new Runnable()....);  
 .....  
 .....  
 Handler.removeMessages(UPDATE_PIC);   


Let's look deeper into the Android framework.
We'll see that setting a runnable to handler and the handler calls getPostMessage(Runnable r) .
Message will find a message instance which is used before and recycled in the message pool, if there is one.
Otherwise, just create new one.
Then, handler use the message to wrap this runnable.

 public final boolean post(Runnable r)  
 {  
     return sendMessageDelayed(getPostMessage(r), 0);  
 }  
 private static Message getPostMessage(Runnable r) {  
     Message m = Message.obtain();  
     m.callback = r;  
     return m;  
 }  


Let's check the what variable in Message class.

 Class Message {  
   public int what;  
   .....

   void recycleUnchecked() {
        // Mark the message as in use while it remains in the recycled object pool.
        // Clear out all other details.
        flags = FLAG_IN_USE;
        what = 0;
        arg1 = 0;
        arg2 = 0;
        .....
   }  
 }  

The default value of primitive type int in Java is zero.
Also, even the message is recycled, the what variable is reset to zero.
After handler gets a message from pool or a new one, it doesn't set the what variable.
Thus, all the what variable wrapped by message class is zero.

If someone removes the message with what = 0, all the messages with what = 0 and runnables  will be removed.

In conclusion, Do not use 0 value as the value of what variable in message instance.

2015年3月31日 星期二

Setting SIP phone in Android L



In Android L, you can't find the SIP account in setting.

The SIP function is moved to phone app.

Let's follow these steps:

1. Go to phone app.































2. Find settings.



























































3. Choose "Calls".





























4. Choose "Calling accounts".






























5. Choose "SIP account".






























6. Then add an account.

2014年6月18日 星期三

How to load array from xml in Android?

How to load array from xml in Android?
These are the code I found in Android framework/base/core.

Here is the example.

First, the array.xml is below:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <array name="lockscreen_targets_when_silent">
        <item>@drawable/ima_btn</item>
        <item>@drawable/images</item>
    </array>
</resources>




Then, you can use these code to get the items from the array.
The parameter of the obtainTypedArray() is the array which you want to get the item from.

TypedArray typAry = getResources().obtainTypedArray(
        R.array.lockscreen_targets_when_silent);
        for (int i = 0; i < typAry.length(); i++) {
            TypedValue value = typAry.peekValue(i);
            Log.d(TAG, "get resourceId: " + value.resourceId + ", 
            get ResourceName: " + getResources().getResourceName(value.resourceId));

2013年11月20日 星期三

Scale the view contains stroke with anti-aliasing

How to filter anti-aliasing when we scale the view contains stroke?

Situation:
We have a view which contains stroke on portrait mode and the size of the view is 1000*1000.
On landscape mode, the size will change to 500*500.
According to this requirement, we need to scaling this view includes a canvas.
Remember that we don't change the view size on landscape mode, just scale it.
That is , the size of the view is 1000*1000 on portrait and landscape mode.

First, we calculate the scale rate.
Because of the different size on different mode, we can get the rate:
500/1000 = 0.5

rate = 0.5;
setScaleX(rate);
setScaleY(rate);
canvas.scale(rate, rate);

In order to the scaling action, the position of the view and event are incorrect.
Thus, we need to correct them.

Use these two function to modify the position.
setTranslationX(translationX);
setTranslationY(translationY);

Modify the event for down, move and up.
event.getX() / rate
event.getY() / rate

Finally,
invalidate();

Of cause, when we turn to portrait mode and we need to reset all of them.

 if (orientation == Configuration.ORIENTATION_PORTRAIT) {
      rate = (float) 1.0;
      setScaleX(rate);
      setScaleY(rate);
      if (this.getX() != 0) {
          setTranslationX(0);
      }
      if (this.getY() != 0) {
          setTranslationY(0);
      }
      canvas.scale(rate, rate);
      invalidate();
 }


Display toast on Lockscreen

How to display a toast on Lockscreen?

Situation:
We want to display a toast on Lockscreen.
However, in order to the priority , we can't display a toast on Lockscreen.
In fact, the toast is showing behind the lockscreen.
How we solve this problem?


Solution:
We need to imitate the toast's behavior.
That is, we create a view and set the animation of fade in and fad out .

Here are the example:
LinearLayout layout = (LinearLayout)this.mLayoutInflater.inflate(layout.xml);

LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

addView(layout, lp);
// fade in animation
Animation anmationFirst = new AlphaAnimation(0.0f, 1.0f);
anmationFirst .setDuration(2500);
layout.setAnimation(anmationFirst);

// fade out animation
final Animation anmationSecond = new AlphaAnimation(1.0f, 0.0f);
anmationSecond.setDuration(2500);
layout.setAnimation(anmationSecond);
anmationFirst.startNow();
anmationFirst.setAnimationListener(new AnimationListener() {

     @Override
     public void onAnimationEnd(Animation arg0) {

         // after the first animation finished,
         // start the second animation
         anmationSecond.startNow();
     }

     @Override
     public void onAnimationRepeat(Animation arg0) {

     }

     @Override
     public void onAnimationStart(Animation arg0) {

     }

});



anmationSecond.setAnimationListener(new AnimationListener() {

      @Override
      public void onAnimationEnd(Animation arg0) {

         layout.setVisibility(View.GONE);
      }

      @Override
      public void onAnimationRepeat(Animation arg0) {

      }

      @Override
      public void onAnimationStart(Animation arg0) {

      }
});