當前位置:首頁 » 操作系統 » system源碼

system源碼

發布時間: 2023-01-14 08:32:06

A. View源碼——fitSystemWindows詳解

該方法在窗口的insets發生變化時,被調用。View調用該方法,以調整內容來適應窗口的變化。窗口的insets變化,包括status bar、軟鍵盤、navigation bar等的顯隱。
一般情況下我們不需要關心這個方法。但如果設置 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN、SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 等標識開啟沉浸式,默認情況下,我們的內容區域就會被status bar、軟鍵盤等遮擋。
該方法的默認實現會根據insets值來設置view的padding,並返回true,防止該事件繼續傳遞(即只有一個view會真正fitSystemWindows)。要開啟該方法,需要執行 setFitsSystemWindows(true) ,或在XML中設置 android:fitsSystemWindows="true" 。
如果只需要為XML文件的根布局設置fitSystemWindows,該方法的默認實現就能滿足。如果需要適配更加復雜的布局(比如有兩個子View,一個在頂部,一個在底部,則頂部的需要根據insets設置paddingTop,底部的需要根據insets設置paddingBottom),你就需要重寫該方法,自行處理insets。
需要說明的是,如果不做任何處理,所有view接收到的insets都是一樣的(比如top是status bar的高度,bottom是軟鍵盤的高度)。該方法的執行在layout之前。

WindowInsets

該類封裝了幾種不同的insets。 mSystemWindowInsets 對應status bar、軟鍵盤等引起的insets。可用方法如下:

獲取四個邊的inset

消費掉insets,使之不再傳遞

生成新的WindowInsets對象

該方法會被第一個調用,如果設置了listener,則執行自定義的listener,否則執行 onApplyWindowInsets 。

默認情況下該方法會執行第一個分支,即執行上面的 fitSystemWindows 。api20以上,android建議覆寫該方法,而不是已廢棄的 fitSystemWindows 。

監聽fitSystemWindow事件。
listener類如下:

ViewGroup:

可以看到,從根布局開始,先執行本身的 super.dispatchApplyWindowInsets 方法,然後遍歷執行子View的 dispatchApplyWindowInsets 方法,如果被消費掉,則停止傳遞。

布局如下:

設置沉浸式:

設置軟鍵盤適配方式:

現在布局是這個樣子的:

圖1標題欄被狀態欄遮擋,圖2頁面被軟鍵盤遮擋。

再次強調一個概念,默認情況下,設置 android:fitsSystemWindows="true" 只有一個View會生效。

為根布局設置 android:fitsSystemWindows="true" ,同時為了方便觀察,給根布局設置一個灰色背景:

可以看到已經適配了軟鍵盤,但頂部toolbar區域也顯示了根布局的灰色背景,顯然默認實現滿足不了我們的需求。

解決方式有很多,這里介紹兩種比較優雅的方式。

首先需要為Toolbar也設置 android:fitsSystemWindows="true"

達到了預期效果。

自定義根布局

自定義toolbar

兩種方法實際上是等價,不過顯然還是第一種方式更友好,只需要設置一個listener就能搞定,但因為api版本限制,所以很多情況下還是要使用第二種方式。

如果覆寫了 fitSystemWindows(insets) 或者 onApplyWindowInsets(WindowInsets) ,覆寫方法中不調用對應的super方法,則不需要設置 setFitsSystemWindows(true) 或者 android:fitsSystemWindows="true" 。

原因如下:

B. System.loadLibrary源碼分析

現在越來越多的項目都會使用第三方so庫,提交so庫,那麼自然想到的就是so庫的導入,很多在使用so庫的時候莫名會出現很多問題,不管是導庫的過程,還是使用so庫方法時。如果你對so使用一無所知,那麼接下來的幾篇文章將對你很有幫助,我會從淺到深將整個過程講解清楚。

Android8.0

這里可以看出VMStack.getCallingClassLoader()返回的是PathClassLoader載入器對象。

到此System.loadLibrary就分析到這里,想要了解JNI動態注冊的可以直接看下一篇文章。 動態注冊JNI方法

C. java源碼的問題System.out.println(str)

system類最後有這么一個方法initializeSystemClass()
這個方法有setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
這句話就初始化了out,所以我們用的out並不是null

D. java System 類里out和err怎麼賦值的沒找到源碼 initializeSystemClass也沒有找到....求大神講解一下

這是initializeSystemClass 源碼,就在 System 類中,在System類的源碼中搜索一下initializeSystemClass 就可以找到了。


(){

props=newProperties();
initProperties(props);//initializedbytheVM


sun.misc.VM.saveAndRemoveProperties(props);


lineSeparator=props.getProperty("line.separator");
sun.misc.Version.init();

FileInputStreamfdIn=newFileInputStream(FileDescriptor.in);
FileOutputStreamfdOut=newFileOutputStream(FileDescriptor.out);
FileOutputStreamfdErr=newFileOutputStream(FileDescriptor.err);
setIn0(newBufferedInputStream(fdIn));
setOut0(newPrintStream(fdOut,props.getProperty("sun.stdout.encoding")));
setErr0(newPrintStream(fdErr,props.getProperty("sun.stderr.encoding")));


loadLibrary("zip");

//SetupJavasignalhandlersforHUP,TERM,andINT(whereavailable).
Terminator.setup();


sun.misc.VM.initializeOSEnvironment();


Threadcurrent=Thread.currentThread();
current.getThreadGroup().add(current);

//registersharedsecrets
setJavaLangAccess();


sun.misc.VM.booted();
}

其中這幾句代碼就是用來初始化,標准輸入流,標准輸出流,標准錯誤輸出流的。

FileInputStreamfdIn=newFileInputStream(FileDescriptor.in);
FileOutputStreamfdOut=newFileOutputStream(FileDescriptor.out);
FileOutputStreamfdErr=newFileOutputStream(FileDescriptor.err);
setIn0(newBufferedInputStream(fdIn));
setOut0(newPrintStream(fdOut,props.getProperty("sun.stdout.encoding")));
setErr0(newPrintStream(fdErr,props.getProperty("sun.stderr.encoding")));

這其中 setOut0 就是用來設置 System.out 的,setOut0 看不到源碼的,它是在java虛擬中的。

E. system在C語言里是什麼意思

system()函數功能強大,很多人用卻對它的原理知之甚少先看linux版system函數的源碼:#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>

int system(const char * cmdstring)
{
pid_t pid;
int status;

if(cmdstring == NULL){
return (1);
}

if((pid = fork())<0){
status = -1;
}
else if(pid = 0){
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
-exit(127); //子進程正常執行則不會執行此語句
}
else{
while(waitpid(pid, &status, 0) < 0){
if(errno != EINTER){
status = -1;
break;
}
}
}
return status;
}
分析一下原理估計就能看懂了:

當system接受的命令為NULL時直接返回,否則fork出一個子進程,因為fork在兩個進程:父進程和子進程中都返回,這里要檢查返回的pid,fork在子進程中返回0,在父進程中返回子進程的pid,父進程使用waitpid等待子進程結束,子進程則是調用execl來啟動一個程序代替自己,execl("/bin/sh", "sh", "-c", cmdstring, (char*)0)是調用shell,這個shell的路徑是/bin/sh,後面的字元串都是參數,然後子進程就變成了一個shell進程,這個shell的參數是cmdstring,就是system接受的參數。在windows中的shell是command,想必大家很熟悉shell接受命令之後做的事了。

再解釋下fork的原理:當一個進程A調用fork時,系統內核創建一個新的進程B,並將A的內存映像復制到B的進程空間中,因為A和B是一樣的,那麼他們怎麼知道自己是父進程還是子進程呢,看fork的返回值就知道,上面也說了fork在子進程中返回0,在父進程中返回子進程的pid。
windows中的情況也類似,就是execl換了個又臭又長的名字,參數名也換的看了讓人發暈的,我在MSDN中找到了原型,給大家看看:
HINSTANCE ShellExecute(
HWND hwnd,
LPCTSTR lpVerb,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);
用法見下:
ShellExecute(NULL, "open", "c:\\a.reg", NULL, NULL, SW_SHOWNORMAL);

你也許會奇怪 ShellExecute中有個用來傳遞父進程環境變數的參數 lpDirectory,linux中的execl卻沒有,這是因為execl是編譯器的函數(在一定程度上隱藏具體系統實現),在linux中它會接著產生一個linux系統的調用 execve, 原型見下:
int execve(const char * file,const char **argv,const char **envp);

看到這里就會明白為什麼system()會接受父進程的環境變數,但是用system改變環境變數後,system一返回主函數還是沒變。原因從system的實現可以看到,它是通過產生新進程實現的,從我的分析中可以看到父進程和子進程間沒有進程通信,子進程自然改變不了父進程的環境變數。
使用了system函數就能執行dos指令。
#include <stdio.h>
#include <stdlib.h>
xiaoyu()
{
char *a;
int n=0;
FILE *f;
f=fopen("file.bat","w+");/*新建一個批處理*/
if(f==NULL)
exit(1);
a="echo"; /*DOS命令*/
for(n=65;n<=90;n++)/*大寫A-Z*/
fprintf(f,"%s %c\n",a,n);/*利用ASCII碼輸出A-Z,寫出批處理*/
fclose(f);
system("file.bat");/*運行批處理*/
}
main()
{
char *string;
xiaoyu();
string="echo C語言的system函數\n";/*輸出中文*/
system(string);
system("pause");/*程序暫停*/
}
C中可以使用DOS命令,以後編程通過調用DOS命令很多操作就簡單多了。

F. 100分求 #include"system.h" 文件或者system.h源代碼

/***
*system.c - pass a command line to the shell
*
* Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
*
*Purpose:
* defines system() - passes a command to the shell
*
*******************************************************************************/#include <cruntime.h>
#include <process.h>
#include <io.h>
#include <stdlib.h>
#include <errno.h>
#include <tchar.h>
#include <dbgint.h>/***
*int system(command) - send the command line to a shell
*
*Purpose:
* Executes a shell and passes the command line to it.
* If command is NULL, determine if a command processor exists.
* The command processor is described by the environment variable
* COMSPEC. If that environment variable does not exist, try the
* name "cmd.exe" for Windows NT and "command.com" for Windows '95.
*
*Entry:
* char *command - command to pass to the shell (if NULL, just determine
* if command processor exists)
*
*Exit:
* if command != NULL returns status of the shell
* if command == NULL returns non-zero if CP exists, zero if CP doesn't exist
*
*Exceptions:
*
*******************************************************************************/int __cdecl _tsystem (
const _TSCHAR *command
)
{
int catch;
_TSCHAR *argv[4]; argv[0] = _tgetenv(_T("COMSPEC")); /*
* If command == NULL, return true IFF %COMSPEC%
* is set AND the file it points to exists.
*/ if (command == NULL) {
return argv[0] == NULL ? 0 : (!_taccess(argv[0],0));
} _ASSERTE(*command != _T('\0')); argv[1] = _T("/c");
argv[2] = (_TSCHAR *) command;
argv[3] = NULL; /* If there is a COMSPEC defined, try spawning the shell */ if (argv[0]) /* Do not try to spawn the null string */
if ((catch = _tspawnve(_P_WAIT,argv[0],argv,NULL)) != -1
|| (errno != ENOENT && errno != EACCES))
return(catch); /* No COMSPEC so set argv[0] to what COMSPEC should be. */
argv[0] = ( _osver & 0x8000 ) ? _T("command.com") : _T("cmd.exe"); /* Let the _spawnvpe routine do the path search and spawn. */ return(_tspawnvpe(_P_WAIT,argv[0],argv,NULL));
}

熱點內容
取消電腦連接wifi密碼怎麼設置密碼 發布:2025-07-04 19:31:32 瀏覽:506
電腦伺服器市場 發布:2025-07-04 19:14:06 瀏覽:503
沒簽名只加密 發布:2025-07-04 18:54:38 瀏覽:255
紅米手機存儲問題 發布:2025-07-04 18:50:43 瀏覽:843
水電煤演算法 發布:2025-07-04 18:36:44 瀏覽:330
天翼視訊緩存文件夾 發布:2025-07-04 18:36:43 瀏覽:97
unix網路編程第2卷 發布:2025-07-04 18:33:41 瀏覽:782
編譯歷史 發布:2025-07-04 18:23:01 瀏覽:852
空調壓縮機種類 發布:2025-07-04 18:13:58 瀏覽:243
中國有ip6伺服器嗎 發布:2025-07-04 17:58:56 瀏覽:727