embedded linux ,android

2010年10月29日 星期五

Android Activity 生命週期



這篇文章將介紹Activity的生命週期
利用一個demo project 
您可以測試各種情況下 activity 的呼叫流程






activitydemo.java
package com.wandroide.tw;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class activitydemo extends Activity {
    private static final String TAG = "ActivityDemo";
  
    private EditText mEditText = null;
    private String   mString   = null;
    private Button   mButton   = null;
  
    private Button.OnClickListener button_listener = new OnClickListener()
    {
 public void onClick(View v)
 {
     Intent intent = new Intent();
            intent.setClass(activitydemo.this, otheractivity.class);
     startActivity(intent);
        } 
    };
    
    /** 
     * 程式一執行就執行onCreate()
     * 所以初始化工作要在這邊做 
     * 或 
     * 當程式執行過onDestory() 被銷毀後
     * 再去按此程式 就會進來執行
     * 這時候程式還沒顯示在裝置螢幕上*/
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mEditText = (EditText)findViewById(R.id.editText);
        mButton=(Button)findViewById(R.id.button);
        mButton.setOnClickListener(button_listener);
        Log.e(TAG, "----onCreate----");
        if( savedInstanceState != null )
        {
            mString = savedInstanceState.getString("EditTextValue");
            Log.e(TAG, "====mString =" + mString );
        }
     }
    
    /** 
     * 執行完onCreate()後 就會執行onStart()
     * 或
     * 程式執行完onStop()後 再回到此程式 則會執行onRestart()-->onStart() 
     * 這個時候程式介面已經顯示在裝置螢幕上
     * 但還無法跟user互動*/
    @Override  
    protected void onStart() 
    {  
        super.onStart();
        Log.e(TAG, "----onStart----");
        if( mString != null )
        {
            mEditText.setText(mString);
            Log.e(TAG, "====mString =" + mString );
        }
     }  
     
    /** 
     * 程式執行完onStop()後 再回到此程式 
     * 則會執行onRestart() */
    @Override  
    protected void onRestart() 
    {  
        super.onRestart();  
        Log.e(TAG, "----onRestart----");  
    }  
     
    /** 
     * 執行完onStart()後 就會執行onResume()
     * 或
     * 程式執行完onPause()後 再回到前景 則會執行onResume() 
     * 這個時候程式介面顯示在裝置螢幕上
     * 而且可以跟user互動*/
    @Override  
    protected void onResume() 
    {  
        super.onResume();  
        Log.e(TAG, "----onResume----");  
    }  
     
    /** 
     * 畫面被另一個activity遮住或遮住一部分
     * 就會執行onPause() 
     * 這個時候程式介面顯示在裝置螢幕上
     * 但無法跟user互動*/
    @Override  
    protected void onPause() 
    {  
        super.onPause();
        Log.e(TAG, "----onPause----");
    }  
     
    /** 
     * 執行onPause()後 就會執行onStop() 
     * 這個時候程式介面沒有在裝置螢幕上*/
    @Override  
    protected void onStop() 
    {  
        super.onStop();  
        Log.e(TAG, "----onStop----");  
    }  
    
    /** 
     * 執行onStop()後 就會執行onDestory() 
     * 這個時候程式介面沒有在裝置螢幕上*/  
    @Override  
    protected void onDestroy() 
    {  
        super.onDestroy();  
        Log.e(TAG, "----onDestroy----");  
    }  
    
    /** 
     * 有另一個activity開啟時 會執行onSaveInstanceState()
     * 若此activity被destory後 再執行此activity 
     * 或
     * 切換螢幕方向 Ctrl + F12 則執行此函數
     * 且onCreate() 帶著savedInstanceState參數 */  
    @Override
    protected void onSaveInstanceState(Bundle outState) 
    {  
        super.onSaveInstanceState(outState);
        mString = mEditText.getText().toString();
        outState.putString("EditTextValue",mString);
        Log.e(TAG, "----onSaveInstanceState----");  
    } 
    
    /** 
     * 切換螢幕方向 Ctrl + F12
    * onDestory() --> onCreate(帶著savedInstanceState參數)
    * --> onStart() --> onRestoreInstanceState(帶著savedInstanceState參數) 
     * --> onResume() */
    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) 
    {
        super.onRestoreInstanceState(savedInstanceState);
        String myString = savedInstanceState.getString("EditTextValue");
        Log.e(TAG, "----onRestoreInstanceState----");
        Log.e(TAG, "====myString =" + myString );
    }
}

otheractivity.java
package com.wandroide.tw;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class otheractivity extends Activity {
    private static final String TAG = "OtherActivity";
  
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.other);
        Log.e(TAG, "----other onCreate----");
    }
    
    @Override  
    protected void onStart() 
    {  
        super.onStart();  
        Log.e(TAG, "----other onStart----");  
    }  
     
    @Override  
    protected void onRestart() 
    {  
        super.onRestart();  
        Log.e(TAG, "----other onRestart----");  
    }  
     
    @Override  
    protected void onResume() 
    {  
        super.onResume();  
        Log.e(TAG, "----other onResume----");  
    }  
     
    @Override  
    protected void onPause() 
    {  
        super.onPause();
        Log.e(TAG, "----other onPause----");  
    }  
     
    @Override  
    protected void onStop() 
    {  
        super.onStop();  
        Log.e(TAG, "----other onStop----");  
    }  
    
    @Override  
    protected void onDestroy() 
    {  
        super.onDestroy();  
        Log.e(TAG, "----other onDestroy----");  
    }  
    
    @Override
    protected void onSaveInstanceState(Bundle outState) 
    {  
        super.onSaveInstanceState(outState);
        Log.e(TAG, "----other onSaveInstanceState----");  
    } 
    
    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) 
    {
        super.onRestoreInstanceState(savedInstanceState);
        Log.e(TAG, "----other onRestoreInstanceState----");
    }
}

2010年10月27日 星期三

Debug mode on Eclipse 與 logcat 使用

1. 開啟 Eclipse
2. 按兩下左鍵設定中斷點








3.  在 Package Explorer 專案中按右鍵出現選單,選取 Debug as --> 2 Android Application
4. 接著按右上角,選取Debug,轉換成 debug mode






接著示範 logcat 的使用


1. 選取 windows --> show view --> others --> android --> logcat,開啟 logcat
2.


























3. 在 debug mode 執行此程式





將android framework source 加入Eclipse

從網路上看到將 Android Framework Source
( Java code ) 加入 Eclipse 的 Script "fix_android_sdk.py".
下面是實際操作的截圖





















































android module編譯與envsetup.sh

這篇文章在說明如何部分編譯
與使用envsetup.sh
以下是操作截圖


Android Overview

本篇文章重點在透過 Android Source Code 資料夾架構說明一些 Android 細節,包含四層架構與並以 Jollen Mokoid 為例大致介紹如何擴充 Android framework,讓大家對 Android 有系統層面的了解。

嵌入式 Linux 系統主要分成三個部份,包含 BootLoader ( 一般為 UbootKernelRootFileSystemAndoird 第一層即是修改過的 Linux Kernel,第二層以上就是一般所謂的 RootFileSystem

圖1:Android階層圖

Andoird 實驗版 SDKAndroid Source 資料夾如下
圖2. android source











  • bionicGoogle 自己開發的Libc.
  • build:Android Building System.
  • development:應用程式開發的模組及工具.
  • hardware:建立HAL的函式庫.
  • out:編譯android source得到的image產生在這裡.
  • vendor:避免與原始的source code混雜廠商開發的應用程式及framwwork擴充放這邊.
  • dalvik:Google自己開發基於register的JVM據說針對手持裝置優化過.
  • external:opensource project.
  • frameworks:android階層圖第二層與第三層code放這裡.
  • packages:android標準的應用程式.


接下來利Jollen Mokoid 專案 Overview 一下如何由底層打通到上層









Mokoid 專案是控制 dma6410l 實驗版上的 Led,資料夾裡配置了 Android.mk ( 給 compiler吃的資訊檔 ),apps ( 放自行開發的應用程式 ),dma6410xp ( 配置新的產品分支 ),frameworks ( 擴充框架透過 JNI 讓上下層溝通 ),hardware ( 硬體抽象層實作 ),driverLed Linux DriverAndroid 架構裡是不需要的。


















撰寫 Linux Driver 主要分成兩個部分,一部分是實際與硬體溝通的程式碼,另一部份是與 Linux Kernel 溝通的程式碼 ,編譯成 led.ko,所以第四層driver 就搞定了。



與硬體溝通的部份



























































與kernel溝通的部份








































































接著往上走一層第三層HAL 與 Library 的部份,透過 struct HAL_MODULE_INFO_SYMhw_module_t hw_device_t 建構 HAL,根據 Android.mk 知道這部分被編譯成 led.goldfish.so 放在 system/lib/hw 下面 。
























再往上走一層,來到第二層 framework ,這一層分層兩部份,其一為 JNI ( base/service/jni ) 的部份,被編譯成 libmokoid_runtime.so (此部份為第三層library層),另一為 Service ( base/service/java) Manager ( base/core/java ) 的部份,被編譯成 mokoid.jarService 呼叫 JNI function,而 Manager 透過 ILedService.aidl呼叫 Service function,這部份會在之後解釋,在這裡先有個概念即可 

























最後,就是最上層第四層應用程式,利用 ServiceManager.addServiceLedService 加進Android System,應用程式透過 ServiceManager.getService 抓出來使用,這部分檔案編譯成 LedTest.apk,這部份會在之後講解。