当前位置:首页 » 操作系统 » 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));
}

热点内容
长城h6第三代都有哪些配置 发布:2025-07-05 00:39:25 浏览:396
unix系统编程手册 发布:2025-07-05 00:32:17 浏览:285
重庆压缩机厂 发布:2025-07-05 00:14:53 浏览:757
php55兼容 发布:2025-07-05 00:14:52 浏览:545
公主出国访问 发布:2025-07-05 00:13:26 浏览:570
服务器IP作为登录IP 发布:2025-07-05 00:10:56 浏览:979
防雷支架应配置什么电缆 发布:2025-07-05 00:05:56 浏览:220
iosc语言函数 发布:2025-07-05 00:02:40 浏览:994
android打飞机 发布:2025-07-04 23:59:34 浏览:210
mr底层算法 发布:2025-07-04 23:14:59 浏览:781