編輯:關於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、定義一些在時間片的線程與一些函數之間互相調用的變量
Android 中無法取消標題欄的問題小結(兩種方法)
我們都知道取消標題欄有兩種方式,一種是在Java代碼中取消,另一種通過設置styles.xml文件中的Theme即可;如下圖:第一種:第二種:但是運行在Android 5
Android百日程序:嵌入Fragment
Fragment相當於一個小型activity,因為Fragment可以實現activity中所有的功能,不同的是Fragment可以嵌入activity,一個activ
Android開發UI特效
Android中UI特效 android經典開源代碼分享 本文原始網址 作者為23code,歡迎給作者投稿 其它UI相關的網址: https://github.co
基於GridView和ActivityGroup實現的TAB分頁(附源碼)
分頁大家都會用Android的TabHost和TabActivity的組合,今天我這裡實現的是GridView和ActivityGroup實現的分頁,這裡需要將Activ