Building Ice Cream Sandwich (Android v4) for VirtualBox on EC2_virutalbox+ android v4.0 ice cream sandwich-程序员宅基地

From:

http://www.thatsgeeky.com/2011/12/building-ice-cream-sandwich-android-v4-for-virtualbox-on-ec2/

相关:

http://android-x86.sceners.org/en/?p=105

http://www.borncity.com/blog/category/android/

http://open-nfc.org/wp/2013/04/25/new-virtualbox-appliance-embedding-open-nfc-for-android/


This was completed 2 weeks ago, but I am only now getting around to posting it online. This experiment was purely for the fun of it – I don’t own (or want) a cell phone, and have never used Android. However, it is an interesting operating system, and I always enjoy playing around with such things – it’s the process more than the end result.

Android 4 – Ice Cream Sandwich (ICS) is more compatible with x86 architectures than previous versions, and even includes a VirtualBox make profile. The default build, however, lacks a few things. Notable among these are mouse support, and network DNS (networking is enabled though).

One of the differences in my approach, is that I used Amazon’s EC2 to do my compiling (mostly because it let me download the few GB of files in a few minutes, and I could throw as much disk space and processor power as I wanted at the task for relatively minimal cost).

Estimated time: 2 hours
Cost (on EC2): $0.45 (2x$0.216 + misc)

Since EC2 has a variety of instances, it helps to know what is the limiting factor in compiling – CPU, memory, or I/O.

I/O is dealt with by using a RAID0 array of ephemeral disks. The xlarge instances provide 4 ephemeral disks, which can easily be assembled into a RAID0 set using mdadm. It is worth noting that while many reports do suggest that EBS volumes are faster, with a 4 disk RAID, the performance should be acceptable (and without the cost that would be incurred by using EBS).

That leaves RAM vs CPU. My observations found that the entire process needed about 3GB of memory (although, the Android site recommends 16GB, including swap), but that CPU was easily maxed out. I tried both m2.xlarge and c1.xlarge instances for this task – there really wasn’t as big of a difference as I would have expected (although, the processes weren’t run with the intention of comparing the instances). I would favour the c1.xlarge for this task.

The c1.xlarge has 8 cores (’20 ECUs’) and 7GB of memory – it is comparable to a mid-high end desktop, clocking in at about 75GFLOPS.

The recommended operating system for building Android is Ubuntu 10.04 – however, for interest sake, I opted to use, Ubuntu 11.04. I chose a instance-store AMI (ami-21f53948), since these include the ephemeral storage by default (and have no disk cost associated with them). (The intent here being to save some setup time and, of course, keep costs to a minimum).

To get started, we create a spot request, for one c1.xlarge instance, in any availability zone. At the time of writing, the spot price was $0.216/hr (which is a bit more than the spot price of the m2.xlarge, at $0.153, although, the latter has more variation). Unless you are im a particular hurry, the spot instances are the most cost effective for a fairly short task – just remember to overbid somewhat to prevent unwanted termination in the middle of your task.

Once the instance launches, SSH into it using your keypair (and the username ‘ubuntu’). If, like me, you aren’t used to using Ubuntu AMIs, the default settings (lack of scrollback, status bar at the bottom, the idea of ‘windowed sessions’, etc.) will be a bit alien at first, but it does grow on one.

Initial Preparation

We will begin by getting the instance up to date and installing the necessary dependencies. One point of mention is that Ubuntu 11.04 uses GCC v4.6 – which is not compatible with the Android code (it needs v 4.4).

Since all of the initial commands need elevated privileges, I like to run sudo in interactive mode initially. Just be aware of what you are doing (even if this is a ‘throwaway’ instance). Alternatively, you can prefix each of the first few commands with sudo.

sudo -i
apt-get update
apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev libc6-dev lib32ncurses5-dev ia32-libs x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev g++-multilib mingw32 tofrodos python-markdown libxml2-utils gcc-4.4 g++-4.4 python-lunch gcc-4.4-multilib g++-4.4-multilib

Symlink one file to resolve some naming issues:

ln -s /usr/lib/i386-linux-gnu/libX11.so.6 /usr/lib/i386-linux-gnu/libX11.so

 

RAID0 Setup

Now, of the three major determinants of compile speed (CPU, memory, and I/O) the choice of instance type has addressed the first two, and partly addressed the third. Given 4 ephemeral disks, and at the cost of a few CPU cycles, we can assemble them up in a (software) RAID0 setup.

We will use the ‘multiple device administration’ tool (mdadm) for creating the softRAID. (Answer ‘y’ (yes) to the warning that the disks contain an ext2fs file system.) and will format it to ext4.

apt-get install mdadm
umount /mnt
mdadm --create --verbose /dev/md0 --level=0 --raid-devices=4 /dev/xvdb /dev/xvdc /dev/xvdd /dev/xvde
mkfs.ext4 /dev/md0
mount /dev/md0 /mnt

 

SWAP Setup

The Android documentation recommends a combined total of 16GB of RAM + Swap. We have 7GB of RAM on this instance, but since we have an abundance of available space, we will add 20GB of swap space, on our new RAID0 device. I actually didn’t find the instance needing more than about 3GB of RAM at most during this procedure, but since the setup is easy, there is no harm having the SWAP available.

dd if=/dev/zero of=/mnt/swapfile bs=10M count=2048
mkswap /mnt/swapfile
swapon /mnt/swapfile

 

 VirtualBox

One of the last steps of the compilation process uses Virtualbox’s VBoxManage program to convert an img file to a vdi disk. You can omit this step and do the conversion manually on your own, it works just fine (although, the compile process will display an error at the end if you skip this step).

echo deb http://download.virtualbox.org/virtualbox/debian oneiric contrib >> /etc/apt/sources.list
wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -
apt-get update
apt-get install virtualbox-4.1

 

Java

mkdir -p /opt/java/64/ && cd $_
wget http://download.oracle.com/otn-pub/java/jdk/6u29-b11/jdk-6u29-linux-x64.bin
chmod +x jdk-6u29-linux-x64.bin
./jdk-6u29-linux-x64.bin

 

Directory Setup

mkdir -p /mnt/android/{bin,working_dir}
chown -R ubuntu /mnt/android/

 
We are going to throw in a optional modification that seems to improve the success rate of downloading the Android source:

sysctl -w net.ipv4.tcp_window_scaling=0

 
Finally, we exit the interactive sudo, and resume normal user operations:

exit

 

Prepare the Environment

Note, we have finally logged out of the root user account – the rest of the steps are done as the user ‘ubuntu’.

echo 'export PATH=/mnt/android/bin:/opt/java/64/jdk1.6.0_29/bin:$PATH' >> ~/.profile
export PATH=/mnt/android/bin:/opt/java/64/jdk1.6.0_29/bin:$PATH

 
(The first line above adds the new PATHs to our profile so that if we launch multiple sessions all will have them, the second applies it to our current session).

Download the repo program, and make it executable:

curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > /mnt/android/bin/repo
chmod a+x /mnt/android/bin/repo
cd /mnt/android/working_dir

 

Get the Source

At this point, we are ready to start obtaining the Android source. First we will initialize the repository – the process only takes a few seconds. When asked, enter a name (or alias) and an email address – they are only used if you commit code back to Android, so even a local version will suffice for now. Also, answer ‘y’ (yes) to the two questions.

repo init -u https://android.googlesource.com/platform/manifest

 
A quick note before proceeding: there is a parameter that shows up in many of the following commands ‘j’. It refers to the number of ‘parallel jobs’ that will be executed. Recommended values vary from <CPU Cores>+1 to 2x<CPU Cores>. There are 8 cores (20ECUs) on a c1.xlarge, so I used numbers between 12 and 16 for CPU limited tasks. For higher numbers, I found a high percent of CPU went was used by the kernel scheduler (i.e. high ‘sy’ value in top).

Now to download the source itself – it is on the order of 6GB, so on a normal connection it would take a while – this instance however can download at 300Mbps, so you won’t need to keep this running overnight. This one isn’t CPU limited, so I limited the amount of parallel jobs. (There are some definite pauses in the process, but it completes fast enough). You can go to the next part while this downloads.

repo sync -j4

 

Some time stats:

real    9m6.746s
user    9m58.865s
sys     2m47.034s

 
Now that is a good reason for using EC2 – 9 minutes to download the entire Android source code!

We will import the Android GPG key for authentication. The following command will wait for you to paste the key:

gpg --import

Copy and paste key (from: Android Open Source), press Enter and key in Ctrl+D (End of File) to finish.

Building a new Kernel

Since Android is meant for touchscreen devices, it doesn’t include support for a mouse pointer by default (although, it does, natively, support a mouse). We need to rebuild the kernel with mouse support if we want to use a mouse. (This is a compiling task, and although short, is CPU intensive – we can do it at the same time as the source download though, since that is more of a network limited task). There are, on the order of 1 million files, in about 230MB.

cd /mnt/android
git clone https://android.googlesource.com/kernel/goldfish

 
This will create a new folder with the kernel source (code named ‘goldfish’)

Again, some time stats:

real    2m1.745s
user    1m14.033s
sys     0m14.389s

We switch to the new directory, and checkout the target branch. This finishes in a few seconds:

cd goldfish
git checkout origin/android-goldfish-2.6.29

 

real    0m14.239s
user    0m2.596s
sys     0m1.956s

Now that we have the kernel source, we need to modify the configuration and rebuild it. There is a graphical interface that is included that will allow us to do this quite easily.

cp arch/x86/configs/vbox_defconfig .config
make CC=gcc-4.4 CXX=g++-4.4 ARCH=x86 menuconfig

It will take a few seconds to compile and load. Once it does, use Up/Down arrows to navigate, enter to select (i.e. to expand), ‘y’ (or space) to include. Not being accustomed to the interface, I had expected that expanding a category would show all its sub-items. This is only true if you have selected the category first. An unselected category shows no entries – definitely drove me crazy for a time.

To include mouse support:

  • Select/Expand ‘Device Drivers’
  • Select/Expand ‘Input Device Support’
  • Include ‘Mice’

(You can then expand ‘Mice’ and see the included drivers, in particular, ‘PS/2 mouse’ should be selected)

You can use ‘Esc’ (twice) to work your way out of the program, or repeatedly select ‘Exit’. Remember to save when asked.

Having made the necessary change to the kernel configuration, we can now compile it. It doesn’t take too long, so I picked a low ‘j’ value. It is important to note that if you omit the CC and CCX parameters, that the compile will terminates prematurely (on this setup), without an explicit error, as it will use version 4.6.

make CC=gcc-4.4 CXX=g++-4.4 ARCH=x86 -j8

 
The above command ends with an output similar to the following :

Root device is (202, 1)
Setup is 11180 bytes (padded to 11264 bytes).
System is 2401 kB
CRC a247138c
Kernel: arch/x86/boot/bzImage is ready  (#1)

 
The path to the new kernel is displayed on the last line.

The obligatory time stats:

real    1m37.901s
user    6m17.308s
sys     1m51.835s

 

Replace the Kernel

If the download of the ICS source is complete at this point, you can carry on, otherwise, you will need to take a bit of a break while it finishes.

For interest sake, the location of the kernel that is used by the vbox_x86 build configuration can be determined by the following:

grep "LOCAL_KERNEL :=" /mnt/android/working_dir/build/target/board/vbox_x86/device.mk

We will copy both our new bzImage and vmlinux to overwrite their ICS versions. I don’t think replacing the latter (vmlinux) is strictly necessary, but it worked fine replacing both.

cp /mnt/android/goldfish/arch/x86/boot/bzImage /mnt/android/working_dir/prebuilt/android-x86/kernel/kernel-vbox
cp /mnt/android/goldfish/vmlinux /mnt/android/working_dir/prebuilt/android-x86/kernel/vmlinux-vbox

 

Setup DNS

While networking does function on VirtualBox install of Android, it does not appear to get the default DNS servers. One way around this is to use some publicly available DNS servers, such as those provided by Google (8.8.8.8). We can hard code this into the default properties of our build using the following:

echo "Net.eth0.dns1 = 8.8.8.8"  >> /mnt/android/working_dir/out/target/product/vbox_x86/root/default.prop
echo "Net.dns1 = 8.8.8.8"  >> /mnt/android/working_dir/out/target/product/vbox_x86/root/default.prop

 
We are now, just about ready to start building the code. Firstly, however, we need to finish setting up our environment.

cd /mnt/android/working_dir
. /mnt/android/working_dir/build/envsetup.sh

 
Note: there is a space between the dot and first slash on the above command. The dot is a short form for the ‘source’ command.

Setup the Compiler Cache

As I got used to the layout of the Android code, I found that things didn’t always work out the first time – I sometimes had to compile the code more than once, making slight changes in between. Unfortunately, it takes around an hour to compile. You can greatly reduce the compile time for subsequent compilations (after the first) by use the compiler cache. To set up a 20GB cache, on our RAID disk we can run:

export USE_CCACHE=1
export CCACHE_DIR=/mnt/android/.ccache
prebuilt/linux-x86/ccache/ccache -M 20G

 
If you want to monitor the cache, you can do so using

watch -n1 -d prebuilt/linux-x86/ccache/ccache -s

 

Build ICS

We are now ready to build. The first step is to select the target using lunch.

lunch vbox_x86-eng

 

This will output some information about the build, similar to that below:

PLATFORM_VERSION_CODENAME=AOSP
PLATFORM_VERSION=4.0.1.2.3.4.5.6.7.8.9
TARGET_PRODUCT=vbox_x86
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=x86
TARGET_ARCH_VARIANT=x86
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=OPENMASTER

 

To initialize the build itself, we run make, specifying the correct compiler. I opted to use a ‘j’ value of 12 which seemed to work reasonably.

make CC=gcc-4.4 CXX=g++-4.4 -j12

 
The above process takes just under an hour to complete, as per the time stats below:

real    53m22.432s
user    340m49.770s
sys     38m32.665s

Recompiling, however, (with the cache enabled) takes only about 15 minutes.

The last lines of the output describe the location and size of the image:

Install system fs image: out/target/product/vbox_x86/system.img
out/target/product/vbox_x86/system.img+ total size is 268435456

 

Build the VirtualBox Android Disk

Finally, we build the VirtualBox image we will be using:

make CC=gcc-4.4 CXX=g++-4.4 android_disk_vdi -j12

This process finishes fairly quickly, taking only a few seconds, as below:

real    0m35.250s
user    0m20.629s
sys     0m4.856s

Three images are created (boot, system, userdata) and added to the android_disk.img file. Finally, the image is converted to a VDI format using the VirtualBox tools installed at the beginning. Output resembles the following:

Copying images to specified partition offsets
I/diskutils(32627): Writing RAW image 'out/target/product/vbox_x86/boot.img' to 'out/target/product/vbox_x86/android_disk.img' (offset=17563648)
I/diskutils(32627): Wrote 2738176 bytes to out/target/product/vbox_x86/android_disk.img @ 17563648
I/diskutils(32627): Writing RAW image 'out/target/product/vbox_x86/system.img' to 'out/target/product/vbox_x86/android_disk.img' (offset=28560384)
I/diskutils(32627): Wrote 268435456 bytes to out/target/product/vbox_x86/android_disk.img @ 28560384
I/diskutils(32627): Writing RAW image 'out/target/product/vbox_x86/userdata.img' to 'out/target/product/vbox_x86/android_disk.img' (offset=296996352)
I/diskutils(32627): Wrote 52428800 bytes to out/target/product/vbox_x86/android_disk.img @ 296996352
File edit complete. Wrote 3 images.
Done with bootable android disk image -[ out/target/product/vbox_x86/android_disk.img ]-

Converting from raw image file="out/target/product/vbox_x86/android_disk.img" to file="out/target/product/vbox_x86/android_disk.vdi"...
Creating dynamic image with size 349425664 bytes (334MB)...
Done with VirtualBox bootable disk image -[ out/target/product/vbox_x86/android_disk.vdi ]-

 

Build the VirtualBox Android Installer

Alternatively, you can create an Android Installer disk instead. The resulting process takes a bit longer, and produces a larger image. To do so, run the following (instead of the command above):

make CC=gcc-4.4 CXX=g++-4.4 installer_vdi -j12

 
End of the output:

Converting from raw image file="out/target/product/vbox_x86/installer.img" to file="out/target/product/vbox_x86/installer.vdi"...
Creating dynamic image with size 529080320 bytes (505MB)...
Done with VirtualBox bootable installer image -[ out/target/product/vbox_x86/installer.vdi ]-

 
Time information:

real    0m53.854s
user    0m21.225s
sys     0m8.601s

 

Converting an IMG to a VDI

If you omitted the VirtualBox install, you can use a command like the following (on Windows) to make the conversion:

"C:\Program Files\Oracle\VirtualBox\VBoxManage" convertfromraw -format VDI android_disk.img android_disk.vdi

 

After all of the above, the relevant files that can be found in out/target/product/vbox_x86 are (the .tgz is from the next step):

-rw-rw-r-- 1 ubuntu ubuntu 349425664 2011-11-27 05:32 android_disk.img
-rw------- 1 ubuntu ubuntu 188751872 2011-11-27 05:45 android_disk.vdi
-rw-rw-r-- 1 ubuntu ubuntu 195125495 2011-11-27 06:01 android_images.tgz
-rw-rw-r-- 1 ubuntu ubuntu   2738176 2011-11-27 05:28 boot.img
-rw-rw-r-- 1 ubuntu ubuntu 529080320 2011-11-27 05:52 installer.img
-rw------- 1 ubuntu ubuntu 196091904 2011-11-27 05:52 installer.vdi
-rw-rw-r-- 1 ubuntu ubuntu    232451 2011-11-27 05:28 ramdisk.img
-rw-r--r-- 1 ubuntu ubuntu 268435456 2011-11-27 05:28 system.img
-rw-r--r-- 1 ubuntu ubuntu  52428800 2011-11-27 05:05 userdata.img

 

Uploading to S3

Given that time an item of consideration on EC2, we do not want to keep our instance running while we download and play around with the images. As such, we can upload them to S3, and then terminate the instance. The simplest way to accomplish this is to use Tim Kay’s aws script:

Create a file with as below, with your Access Key ID (line 1) and Secret Access Key (line 2), and restricted permissions:

vi ~/.awssecret
chmod 600 ~/.awssecret

 
Download the script and install:

curl https://raw.github.com/timkay/aws/master/aws -o aws
perl aws –install

 
Compress the images (significant space savings), and upload to S3 (if you don’t already have an S3 bucket, create one first):

cd out/target/product/vbox_x86
tar -czvf android_images.tgz installer.vdi android_disk.vdi
s3put bucket_name/android_images.tgz /mnt/android/working_dir/out/target/product/vbox_x86/android_images.tgz

 
Once the above command exits, you can terminate your instance if you do not anticipate needing to make changes to your image. Of course, if you expect to need changes, keep the instance around because everything is already setup, and the compiler cache will save a lot of time.

Final Notes

  • RAM usage never went above 50% – it was typically on the order of 3GB, swap was unused
  • CPU was maxed out when compiling (typically 85% us, and 12% sy) – load average hovered around 12 while compiling. Typical steal values were 2-3%
  • The advantage of this approach is that AWS doesn’t charge for data transfer in, and ephemeral disks have no cost for allocated space or I/Os, meaning that you only pay for the instance time and the download of the final product.

 

VirtualBox Setup

Once you have your compiled image, you need to setup VirtualBox to use it.

  • General:
    • Operating System: Linux
    • Version: Other Linux
  • System:
    • Boot from Hard Disk
    • Allocate about 1GB of memory (although, it will run on much less)
    • Enable PAE/NX
  • Display:
    • Allocate some memory to graphics – I go with 64MB
  • Storage:
    • Add your android_disk.vdi as an IDE Hard Disk (not a SATA disk) – remove any SATA controllers
  • Network:
    • Enable Adapter #1 and setup as Bridged Adapter (you need to enable this during the setup of VirtualBox before it can be used here)

Save the settings and start the virtual machine. You may get an error about sound and 16bit displays, but dismiss them for the time being.

Once it boots up, you may get an error regarding low battery (i.e. Connect your Charger), you can dismiss the page using Ctrl+Esc. To capture your mouse, just click inside the VirtualBox window (to uncapture press the right Ctrl key – or whatever your host key is if you changed it).

If you want to use the installer instead of the android_disk.vdi, you should create an additional empty virtual hard drive to which you can install. Select the installer_disk.vdi, using F12. At the GRUB screen, choose “Android Install to /dev/sda from /dev/sdb”, and reboot (use command ‘reboot’) when done, booting from your new device (use F12 to change if needed.)

The speed of the virtual machine was fairly good – everything seemed responsive enough.

Known problems:

  • Sound – haven’t tested it, but I don’t think it would work without some modifications
  • Stability – not so great – it runs, but you do see the occasional error – luckily it just lets you continue and you don’t need to restart the machine.
  • Storage – the default disk needs to be made larger – this is easy enough, but would be worthwhile change.
  • Battery – displaying as discharged, and starts with Connect Charger screen.
  • Network – wireless doesn’t display as connected (even though there is network access).
  • Desktop – can’t set a background – just displays as black with the widgets and controls.
  • Haven’t yet had any success playing a video

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Henry_Wu001/article/details/9093843

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签