編輯:關於Android編程
好記性不如爛筆頭。今天要做的學習是關於bionic目錄下的代碼。
首先需要看的是_errno.c這份代碼。
volatile int* __errno( void ) { return &((volatile int*)__get_tls())[TLS_SLOT_ERRNO]; }從上面可以看出,返回的是一個指向int類型的指針。
volatile關鍵字是一種類型修飾符,用它聲明的類型變量表示可以被某些編譯器未知的因素更改,比如:操作系統、硬件或者其它線程等。由於訪問寄存器的速度要快過RAM,所以編譯器一般都會作減少存取外部RAM的優化。遇到這個關鍵字聲明的變量,編譯器對訪問該變量的代碼就不再進行優化,從而可以提供對特殊地址的穩定訪問。
volatile的本意是“易變的”,不過翻譯成“直接存取原始內存地址”更為合適。“易變”是因為外在因素引起的,象多線程,中斷等,並不是因為用volatile修飾了的變量就是“易變”了,假如沒有外因,即使用volatile定義,它也不會變化。
第二個需要說到的_set_errono.c的這份代碼。
這個函數最終會被系統進行調用。
同時在這個函數裡面,即使數據超過邊界,依舊不會認為是個錯誤。因為在Linux中,錯誤的編碼不會超過131.
if(n > -256) { return __set_errno(-n); } else { return n; }
OpenBSD是一個多平台的,基於4.4BSD的類UNIX操作系統,是BSD衍生出的三種免費操作系統(另外兩種是NetBSD和FreeBSD)之一,被稱為世界上最安全的操作系統
接下來需要學習的是arc4random.c。
static pthread_mutex_t _arc4_lock = PTHREAD_MUTEX_INITIALIZER; #define _ARC4_LOCK() pthread_mutex_lock(&_arc4_lock) #define _ARC4_UNLOCK() pthread_mutex_unlock(&_arc4_lock)
定義鎖的作用是保護文件中的全局的變量。
只要注意這個文件是用來生成0~1之間的隨機數就可以了。
接下來看一下basename.c這個類。
在這個文件中,僅僅存在一個函數,返回的是一個字符串。
if (bname == NULL) { bname = (char *)malloc(MAXPATHLEN); if (bname == NULL) return(NULL); }
接下來看到的這個文件是bionic_clone這個文件。
主要查看裡面的clone方法。
int clone(int (*fn)(void *), void *child_stack, int flags, void* arg, ...) { va_list args; int *parent_tidptr = NULL; void *new_tls = NULL; int *child_tidptr = NULL; int ret; /* extract optional parameters - they are cummulative */ va_start(args, arg); if (flags & (CLONE_PARENT_SETTID|CLONE_SETTLS|CLONE_CHILD_SETTID)) { parent_tidptr = va_arg(args, int*); } if (flags & (CLONE_SETTLS|CLONE_CHILD_SETTID)) { new_tls = va_arg(args, void*); } if (flags & CLONE_CHILD_SETTID) { child_tidptr = va_arg(args, int*); } va_end(args); ret = __bionic_clone(flags, child_stack, parent_tidptr, new_tls, child_tidptr, fn, arg); return ret; }
2、父線程與子線程指針以及返回數值的定義。
接下來查看的文件是clearenv這個文件。
int clearenv(void) { char **P = environ; if (P != NULL) { for (; *P; ++P) *P = NULL; } return 0; }
在dlmalloc文件中要注意下面的方法:
static size_t release_unused_segments(mstate m) { size_t released = 0; msegmentptr pred = &m->seg; msegmentptr sp = pred->next; while (sp != 0) { char* base = sp->base; size_t size = sp->size; msegmentptr next = sp->next; if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { mchunkptr p = align_as_chunk(base); size_t psize = chunksize(p); /* Can unmap if first chunk holds entire segment and not pinned */ if (!cinuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) { tchunkptr tp = (tchunkptr)p; assert(segment_holds(sp, (char*)sp)); if (p == m->dv) { m->dv = 0; m->dvsize = 0; } else { unlink_large_chunk(m, tp); } if (CALL_MUNMAP(base, size) == 0) { released += size; m->footprint -= size; /* unlink obsoleted record */ sp = pred; sp->next = next; } else { /* back out if cannot unmap */ insert_large_chunk(m, tp, psize); } } } pred = sp; sp = next; } return released; }
struct thr_timer { thr_timer_t* next; /* next in free list */ timer_t id; /* TIMER_ID_NONE iff free or dying */ clockid_t clock; pthread_t thread; pthread_attr_t attributes; thr_timer_func_t callback; sigval_t value; /* the following are used to communicate between * the timer thread and the timer_XXX() functions */ pthread_mutex_t mutex; /* lock */ pthread_cond_t cond; /* signal a state change to thread */ int volatile done; /* set by timer_delete */ int volatile stopped; /* set by _start_stop() */ struct timespec volatile expires; /* next expiration time, or 0 */ struct timespec volatile period; /* reload value, or 0 */ int volatile overruns; /* current number of overruns */ };1、指向當前的空閒隊列的指針
2、定義相關的線程 信號量 以及對應的回調的函數
3、定義一些在時間片的線程與一些函數之間互相調用的變量
我們都知道取消標題欄有兩種方式,一種是在Java代碼中取消,另一種通過設置styles.xml文件中的Theme即可;如下圖:第一種:第二種:但是運行在Android 5
Fragment相當於一個小型activity,因為Fragment可以實現activity中所有的功能,不同的是Fragment可以嵌入activity,一個activ
Android中UI特效 android經典開源代碼分享 本文原始網址 作者為23code,歡迎給作者投稿 其它UI相關的網址: https://github.co
分頁大家都會用Android的TabHost和TabActivity的組合,今天我這裡實現的是GridView和ActivityGroup實現的分頁,這裡需要將Activ