android時鍾源碼
A. android 時鍾翻頁特效是怎麼實現的 最好有源碼
能說的具體點嗎??
B. android 怎麼實現計時器時分秒的操作
可以Calendar.getInstance().get(Calendar.HOUR),獲取當前時間,然後計算時間差
C. 如何獲取 Android 設備的CPU核數,時鍾頻率以及內存大小
Device Year Class 的主要功能是根據 CPU核數、時鍾頻率 以及 內存大小 對設備進行分級。代碼很簡單,只包含兩個類:
DeviceInfo-> 獲取設備參數,
YearClass-> 根據參數進行分級。
下表是 Facebook 公司提供的分級標准,其中Year欄表示分級結果。
Year	Cores	Clock	RAM
2008	1	528MHz	192MB
2009	n/a	600MHz	290MB
2010	n/a	1.0GHz	512MB
2011	2	1.2GHz	1GB
2012	4	1.5GHz	1.5GB
2013	n/a	2.0GHz	2GB
2014	n/a	>2GHz	>2GB
關於輸出年份的計算方法可以參考源碼,本文只把一些比較常用的功能抽取出來做一個簡要介紹。
獲取 CPU 核數
我們都知道,Linux 中的設備都是以文件的形式存在,CPU 也不例外,因此 CPU 的文件個數就等價與核數。
Android 的 CPU 設備文件位於/sys/devices/system/cpu/目錄,文件名的的格式為cpu\d+。
?
1
2
3
4
5
6
7
8
9
10
root@generic_x86_64:/sys/devices/system/cpu # ls <b>cpu0</b> cpufreq
cpuidle
kernel_max
modalias
offline
online
possible
power
present
uevent
統計一下文件個數便可以獲得 CPU 核數。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public static int getNumberOfCPUCores() {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
// Gingerbread doesn't support giving a single application access to both cores, but a
// handful of devices (Atrix 4G and Droid X2 for example) were released with a al-core
// chipset and Gingerbread; that can let an app in the background run without impacting
// the foreground application. But for our purposes, it makes them single core.
return 1;
}
int cores;
try {
cores = new File("/sys/devices/system/cpu/").listFiles(CPU_FILTER).length;
} catch (SecurityException e) {
cores = DEVICEINFO_UNKNOWN;
} catch (NullPointerException e) {
cores = DEVICEINFO_UNKNOWN;
}
return cores;
}
private static final FileFilter CPU_FILTER = new FileFilter() {
@Override
public boolean accept(File pathname) {
String path = pathname.getName();
//regex is slow, so checking char by char.
if (path.startsWith("cpu")) {
for (int i = 3; i < path.length(); i++) {
if (path.charAt(i) < '0' || path.charAt(i) > '9') {
return false;
}
}
return true;
}
return false;
}
};
回到頂部
獲取時鍾頻率
獲取時鍾頻率需要讀取系統文件 -/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq或者/proc/cpuinfo。
我的 Android 模擬器中並沒有cpuinfo_max_freq文件,因此只能讀取/proc/cpuinfo。
/proc/cpuinfo包含了很多 cpu 數據。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
processor    : 0
vendor_id    : GenuineIntel
cpu family    : 6
model        : 70
model name    : Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
stepping    : 1
cpu MHz        : 0.000
cache size    : 1024 KB
fdiv_bug    : no
hlt_bug        : no
f00f_bug    : no
coma_bug    : no
fpu        : yes
fpu_exception    : yes
cpuid level    : 4
wp        : yes
代碼如下:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public static int getCPUMaxFreqKHz() {
int maxFreq = DEVICEINFO_UNKNOWN;
try {
for (int i = 0; i < getNumberOfCPUCores(); i++) {
String filename =
"/sys/devices/system/cpu/cpu" + i + "/cpufreq/cpuinfo_max_freq";
File cpuInfoMaxFreqFile = new File(filename);
if (cpuInfoMaxFreqFile.exists()) {
byte[] buffer = new byte[128];
FileInputStream stream = new FileInputStream(cpuInfoMaxFreqFile);
try {
stream.read(buffer);
int endIndex = 0;
//Trim the first number out of the byte buffer.
while (buffer[endIndex] >= '0' && buffer[endIndex] <= '9'
&& endIndex < buffer.length) endIndex++;
String str = new String(buffer, 0, endIndex);
Integer freqBound = Integer.parseInt(str);
if (freqBound > maxFreq) maxFreq = freqBound;
} catch (NumberFormatException e) {
//Fall through and use /proc/cpuinfo.
} finally {
stream.close();
}
}
}
if (maxFreq == DEVICEINFO_UNKNOWN) {
FileInputStream stream = new FileInputStream("/proc/cpuinfo");
try {
int freqBound = parseFileForValue("cpu MHz", stream);
freqBound *= 1000; //MHz -> kHz
if (freqBound > maxFreq) maxFreq = freqBound;
} finally {
stream.close();
}
}
} catch (IOException e) {
maxFreq = DEVICEINFO_UNKNOWN; //Fall through and return unknown.
}
return maxFreq;
}
回到頂部
獲取內存大小
如果 SDK 版本大於等於JELLY_BEAN,可以通過ActivityManager來獲取內從大小。
?
1
2
3
ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
ActivityManager am = (ActivityManager) c.getSystemService(Context.ACTIVITY_SERVICE);
am.getMemoryInfo(memInfo);
如果版本低於JELLY_BEAN,則只能讀取系統文件了。
?
1
2
FileInputStream stream = new FileInputStream("/proc/meminfo");
totalMem = parseFileForValue("MemTotal", stream);
完整代碼如下:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static long getTotalMemory(Context c) {
// memInfo.totalMem not supported in pre-Jelly Bean APIs.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
ActivityManager am = (ActivityManager) c.getSystemService(Context.ACTIVITY_SERVICE);
am.getMemoryInfo(memInfo);
if (memInfo != null) {
return memInfo.totalMem;
} else {
return DEVICEINFO_UNKNOWN;
}
} else {
long totalMem = DEVICEINFO_UNKNOWN;
try {
FileInputStream stream = new FileInputStream("/proc/meminfo");
try {
totalMem = parseFileForValue("MemTotal", stream);
totalMem *= 1024;
} finally {
stream.close();
}
} catch (IOException e) {
}
return totalMem;
}
}
D. android 源碼里有u-boot嗎
本人用的android平台用的bootloader用的是uboot,貌似大多數手持設備平台都不用這個,因為功能過於強大用不上,反而顯得太復雜了。不知道這個平台開發者是怎麼想的。既然用了那就來分析一下,順便修改一下其中的幾個小問題,以符合我們的要求。
  uboot等同於其他所有的bootloader程序,從根本上講是一個稍復雜的裸機程序,是最底層的東西,要分析裸機程序我們要從它的連接文件開始。連 接文件(.lds文件)定義了程序編譯之後整個連接過程,這樣我們就可以找到這個程序的第一句匯編代碼,進而來下一步分析。uboot的鏈接文件代碼在 android\bootable\bootloader\uboot-imx\u-boot.lds
[cpp] view plain
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")  //文件輸出格式  
OUTPUT_ARCH(arm)  
ENTRY(_start)       //首地址標示符  
SECTIONS  
{  
 . = 0x00000000;    //其實地址0  
 . = ALIGN(4);      //4位元組對齊  
 .text :        //代碼段  
 {  
   board/freescale/mx6q_sabresd/flash_header.o (.text.flasheader)   //第一個文件是board/freescale/mx6q_sabresd/flash_header.o  
   cpu/arm_cortexa8/start.o         //第二個cpu/arm_cortexa8/start.o   
   board/freescale/mx6q_sabresd/libmx6q_sabresd.a (.text)  
   lib_arm/libarm.a (.text)  
   net/libnet.a (.text)  
   drivers/mtd/libmtd.a (.text)  
   drivers/mmc/libmmc.a (.text)  
   . = DEFINED(env_offset) ? env_offset : .;  
   common/env_embedded.o(.text)  
   *(.text)             //剩餘的所有代碼  
 }  
 . = ALIGN(4);  
 .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } //readonly data 段  
 . = ALIGN(4);  
 .data : { *(.data) }       //所有的readonly data  
 . = ALIGN(4);  
 .got : { *(.got) }  
 . = .;  
 __u_boot_cmd_start = .;        //u_boot_cmd段,裡面是所有uboot命令的一個列表  
 .u_boot_cmd : { *(.u_boot_cmd) }  
 __u_boot_cmd_end = .;  
 . = ALIGN(4);  
 _end_of_ = .;  
 __bss_start = .;           //bss段 就是內存數據段  
 .bss : { *(.bss) }  
 _end = .;  
}  
從上面的代碼可以看出我們編譯生成的二進制應用程序組成是:代碼段->rodata段->uboot命令列表->bss段。我們啟動這個應用程序時候是從,0地址開始的,因此我們來看
board/freescale/mx6q_sabresd/flash_header.s這個文件。
  這個文件中除了分配內存和宏定義的偽匯編指令以外,真正執行的命令有一條
[cpp] view plain
.section ".text.flasheader", "x"  
    b   _start  
    .org    CONFIG_FLASH_HEADER_OFFSET  
也就是說,這個文件一執行就直接跳到_start 位置處。_start 在android\bootable\bootloader\uboot-imx\cpu\arm_cortexa8\ start.S中,因此我們來看這個文件代碼
[cpp] view plain
.globl _start  
_start: b   reset         
這里直接跳轉的reset中接下來看
[csharp] view plain
reset:  
    /* 
     * set the cpu to SVC32 mode    cpu設置成32位管理模式 
     */  
    mrs r0, cpsr  
    bic r0, r0, #0x1f  
    orr r0, r0, #0xd3  
    msr cpsr,r0  
 
#if (CONFIG_OMAP34XX)   //因為我們的cpu不是ompa的 所以這段不會編譯  
.............................  
#endif  
    /* the mask ROM code should have PLL and others stable */  
#ifndef CONFIG_SKIP_LOWLEVEL_INIT  
    bl  cpu_init_crit         
#endif  
這里接下來執行cpu_init_crit
[csharp] view plain
/************************************************************************* 
 * 
 * CPU_init_critical registers 
 * 
 * setup important registers 
 * setup memory timing 
 * 
 *************************************************************************/  
cpu_init_crit:  
    /* 
     * Invalidate L1 I/D 
     */  
    mov r0, #0          @ set up for MCR  
    mcr p15, 0, r0, c8, c7, 0   @ invalidate TLBs  
    mcr p15, 0, r0, c7, c5, 0   @ invalidate icache  
  
    /* 
     * disable MMU stuff and caches     //關閉mmu 
     */  
    mrc p15, 0, r0, c1, c0, 0  
    bic r0, r0, #0x00002000 @ clear bits 13 (--V-)  
    bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)  
    orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align  
    orr r0, r0, #0x00000800 @ set bit 12 (Z---) BTB  
    mcr p15, 0, r0, c1, c0, 0  
  
    /* 
     * Jump to board specific initialization... 
     * The Mask ROM will have already initialized 
     * basic memory. Go here to bump up clock rate and handle 
     * wake up conditions. 
     */  
    mov ip, lr      @ persevere link reg across call  
    bl  lowlevel_init   @ go setup pll,mux,memory//執行lowlevel_init這個函數代碼在  
                            @\bootloader\uboot-imx\board\freescale\mx6q_sabresd\lowlevel_init.S中  
                            @主要對時鍾,外部ram,rom等進行了初始化代碼不貼了。  
    mov lr, ip      @ restore link  
    mov pc, lr      @ back to my caller  
初始化完成後,接下來執行
[csharp] view plain
#ifndef CONFIG_SKIP_RELOCATE_UBOOT  
relocate:               @ relocate U-Boot to RAM    將uboot重新定位到內存中  
    adr r0, _start      @ r0 <- current position of code  
    ldr r1, _TEXT_BASE      @ test if we run from flash or RAM   
    cmp r0, r1          @ don't reloc ring debug測試當前代碼是否已經在內存中  
    beq stack_setup     @如果在的話就直接跳轉到stack_setup  
ldr r2, _armboot_start  @如果不在的話,載入_armboot_start地址到r2中。_armboot_start是uboot執行的主體c函數。  
    ldr r3, _bss_start  
    sub r2, r3, r2      @ r2 <- size of armboot計算bss_start-armboot_start 保存到R2中,也就是uboot的總大小  
    add r2, r0, r2      @ r2 <- source end address 計算出uboot代碼和rodata地址  
  
_loop:              @  32 bytes at a time   //開始拷貝  
    ldmia   r0!, {r3 - r10}     @  from source address [r0]  
    stmia   r1!, {r3 - r10}     @  to   target address [r1]  
    cmp r0, r2          @ until source end addreee [r2]  
    ble _loop  
#endif  /* CONFIG_SKIP_RELOCATE_UBOOT */
E. 找一款android的時鍾插件,使透明的
Simi Clock Widget數字時鍾,這是一款非常漂亮的數字時鍾插件。可以修改背景、顏色、透明等設置。讓你的桌面時間更加漂亮。 
專業版特性: 
-全新的:新的小工具大小4x2 
-全新:時間的文本樣式(正常,斜體,粗體,斜體加粗+) 
-全新:上午/下午的文本樣式(正常,斜體,粗體,斜體加粗+) 
-全新:日期的文本樣式(正常,斜體,粗體,斜體加粗+) 
-全新:文本的時間陰影 
-全新:文本的上午/下午陰影 
-全新:文本的日期陰影 
-全新:自定義字體(只要你的ttf復制到SD卡,並選擇它) 
V2.6.5更新: 
重新設計的顏色對話框 
修復的問題與小屏幕設備 
新:可以顯示下一個報警 
新:厚度電池圓弧
F. X10 android 時鍾 桌面時鍾 數字時鍾。
按住桌面不動,彈出選擇小插件選項,然後點擊時鍾小插件。
就可把桌面時鍾調出來,不過要預留4個空格位置的屏幕空間才能放出來。
G. android 模擬時鍾 手指觸動旋轉指針
先學會畫時針,然後在觸摸事件里根據傳進來的event拿到手指的坐標值來刷新屏幕重畫時針就好
H. 如何用android設計一個程序包括鬧鍾,時鍾,秒錶,計時
Android的程序界面,找到名為圖標:時鍾,點擊進入四個項目,鬧鍾,世界時鍾,秒錶,倒計時。您可以選擇報警的那一個,看看裡面是否有可以刪除的鬧鍾。
I. 重寫一個帶時分秒的時鍾(Android)
看看源碼,然後重寫。
