Android系统整体结构图
先是从底层看起:(它是从Linux内核里面抽取出来的一部分)
DisplayDriver(显示驱动),CameraDriver(相机驱动),BluetoothDriver(蓝牙驱动)
FlashMemoryDriver(闪存驱动),USBDriver(USB驱动),后面的键盘驱动,WIFI驱动,音频驱动,电池驱动
然后是第二层:
libraies(类库)
SurfaceManager(显示管理器),MediaFramework(多媒体框架),SQLite(数据库,小型数据库),OpenGL|ES(3D图库引擎),SGL(2D图库引擎),FreeType(免费开发的文字显示框架),SSL(一个安全协议),WebKit(浏览器内核),libc(c语言核心库)
Android RunTime(安卓运行时)
里面有DalvikVirtualMachine(DVM),是从jvm里面改进过来的
CoreLibraries(Java的核心库)
然后是第三层(都是Java写的)
对应:活动管理器,窗口管理器,内容提供者,视图系统,通知管理,包管理,电话管理器,资源管理器,定位管理器,XMPP及时通讯协议
然后是第四层
Home(桌面),Contacts(联系人),Phone(电话),Browser(浏览器)
区别DVM与JVM
首要差别
Dalvik: 基于寄存器,编译和运行都会更快些
JVM: 基于栈, 编译和运行都会慢些
字节码的区别
Dalvik: 执行.dex格式的字节码,是对.class文件进行压缩后产生的,文件变小
JVM: 执行.class格式的字节码
运行环境的区别
Dalvik : 一个应用启动都运行一个单独的虚拟机运行在一个单独的进程中
JVM: 只能运行一个实例, 也就是所有应用都运行在同一个JVM中
项目组成结构
自动生成的R.java类里面的结构和对应资源的值
Activity和应用功能清单配置文件
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
/**
* 主界面Activity类,主界面就是点击应用图标启动的界面
*/
public class MainActivity extends AppCompatActivity
{
/**
* 重写方法onCreate:在当前类(activity)对象创建的时候自动调用
* 就是回调方法:不是我们自己调用的,是系统在一定条件下自动调用的,
* 而且在Android中基本是以on开头,这些方法我们不需要调用,一般是重写
*/
@Override
protected void onCreate(Bundle savedInstanceState)
{
//先调用父类做一些默认的初始化工作
super.onCreate(savedInstanceState);
//设置窗口要显示的内容视图(界面或者布局)
//其中参数是一个int类型的数值,是要指定布局文件在R所对应的变量
//这样就可以加载布局文件,让它显示到窗口中
setContentView(R.layout.activity_main);
}
}
<?xml version="1.0" encoding="utf-8"?>
<!--
package属性:指定当前应用唯一包名,这是应用的标识,不同的应用不一样
versionName属性:指定应用的版本号
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication" >
<!--
icon:应用的图标
label:应用的名称
theme:应用的主题
-->
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<!--
activity标签:配置我们的Activity类
name属性:要写全类名的,但是可以省略包名部分
label属性:界面的标题
-->
<activity android:name=".MainActivity" >
<!--让当前Activity成为主界面Activity-->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
res文件夹
res文件夹是资源文件夹,里面还分了很多文件夹
mipmap-xxxdpi:有一系列的这种文件夹,这些是图片文件夹,
而为什么有这么多的文件夹呢?而且每一个文件夹里面存放的图片都是一样的
那是因为手机有好有坏,分辨率不一样,分辨率坏的手机显示这一张图片刚刚好
而分辨率好的手机再显示这一张图片,那么就会变得小了一点,所以这是为了适配不同分辨率的手机
layout:界面的布局文件,功能类似HTML
values:常量文件夹
比如strings.xml里面,就包含固定的字符串,在布局中引用的方式:@string/变量的名称
APK文件
应用打包的过程
Android系统文件目录结构
Android系统就是类似Linux系统一样,里面的存储结构没有分什么C盘D盘之类的
就只有一个盘,里面的
/ 代表系统的根目录
/data/app/ 存放的是第三方的apk文件
/system/app/ 这是系统中安装好的应用文件
/data/data/packagename/ 存放的是以应用对应的文件,在应用安装时自动生成,应用卸载的时候自动删除
/storage/sdcard/ 就是sd卡的文件夹
SDK文件目录结构
/docs
是文档的目录,点击index.html就能查看API文档
/platforms
是每一个版本运行所需要的jar包
/platform-tools
包含一些开发工具,比如adb.exe(真机模拟的连接程序),sqlite3.exe
/samples
一些Google提供的样例项目工程
/source
包含系统的部分原码
/tools
包含一些开发工具,比如hierarachyviewer.bat
/platforms
介绍三个工具
ADB
Android 调试桥(Android Debug Bridge)是多种用途的调试工具帮助你管理设备或模拟器的状态,就是类似之前你们一直使用的debug窗口
常用的命令
adb shell //就是进入你的当前运行的Android系统的根目录,使用ls可以查看当前系统的目录文件
ctrl+c //退出shell,就是退出系统根目录
cls //清屏
adb install –r apkPath -push this package file to the device install,就是安装一个apk文件,就是帮手机安装一个应用,-r意思是如果这个应用已经存在就先删除
DDMS
全称是Dalvik Debug Monitor Service
Android 开发环境中的Dalvik虚拟机调试监控服务
Eclipse中提供的Android应用开发的调试工具
它有四个重要的视窗
Logcat : 查看日志输出:
File Explorer:查看系统内部文件
Devices:显示关联的Android设备
Emulator Control:操作控制关联的Android设备
工具类Log
工具类Log提供了五种的输出的方法,分别是:
v() //对应Verbose级别,显示全部的信息
d() //对应debug级别,显示调试信息
i() //info级别,显示一般信息
w() //warming级别,显示警告信息
e() //Error,显示错误信息
测试
package com.example.hello;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i("jane", "执行了Log.i()");
Log.e("jane", "执行了Log.e()");
}
}
发现LogCat窗口打印的信息超级多,所以使用过滤器进行过滤找到我们想要的信息
这里我们根据包名来过滤,因为一个应用对应一个包名,所以这里肯定是我们写的这个程序输出的信息
下载功能的模拟
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<Button
android:id="@+id/MainButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_marginTop="35dp"
android:text="下载" />
</RelativeLayout>
package com.example.hello;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
/*
Toast: 用来显示短时间提示文本的类
static Toast makeText(...) : 创建一个toast对象
show(): 显示小提示
R: 应用的资源类
R.drawable: 包含所有图片资源标识的内部类
R.layout: 包含所有布局资源标识的内部类
R.id: 包含所有视图id标识的内部类
R.string: 包含所有字符串标识的内部类
*/
public class MainActivity extends Activity
{
//一般会将要操作的组件放在类的变量里面
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//加载布局文件,并在内存中生成对应的视图对象
setContentView(R.layout.activity_main);
Log.i("jane", "ִ执行了Log.i()");
Log.e("jane", "ִ执行了Log.e()");
//根据id在内存中查找对应的视图对象
button = (Button) findViewById(R.id.MainButton);
//给这个button设置监听
button.setOnClickListener(new View.OnClickListener()
{
//这是匿名内部类,下面是点击button的回调方法
@Override
public void onClick(View v)
{
/*
* 下面的回调方法主要的操作是:
* 1.显示文本小提示
* 2.将button的内容更新为下载中...
* 首先是Toast需要的参数问题,需要一个Context类
* 经过查看发现Context接口的实现类有Activity,那么我们现在的类就是,
* 所以就将本类传进去,但是这里是匿名内部类,想得到外部类的当前对象,就使用类名.this获得
* 第三个参数是duration,
* * @param duration How long to display the message. Either {@link #LENGTH_SHORT} or
* {@link #LENGTH_LONG}
* 通过注释可以发现是显示的时间,只有两个取值
*/
Toast toast = Toast.makeText(MainActivity.this, "开始下载...", Toast.LENGTH_LONG);
toast.show();
button.setText("下载中...");
}
});
}
}
手机单位相关的概念
手机的尺寸: 屏幕对角线的长度,单位为英寸(2.54cm)
手机的分辨率: 屏幕能显示的像素的数量, 一般用在长方向上数量*宽方向上数量来表达
手机的像素密度: pixels per inch,也称PPi,即每英寸屏幕能显示的像素数,
像素密度越大,显示画面细节就越丰富。
计算:像素密度={1+√ [(长度像素数-1) ^ 2 +(宽度像素数-1)^2]}/屏幕尺寸
DPI: Dots Per Inch(每英寸所打印的点数或线数)的缩写,
用来表示打印机打印分辨率, 但有时也会用dpi来代指ppi
手机的密度: Density, 以160ppi为基准, 即像素密度为160时Density为1
ldpi 120ppi 0.75
mdpi 160dpi 1.0
hdpi 240dpi 1.5
xhdpi 320dpi 2.0
px: pixels(像素)
1px就的长度就对应屏幕一个像素点的大小,但是这个单位在不同的手机一个像素点的大小不一样
比如手机的大小都一样的情况下,如果好的手机在横的方向能放下的像素点有800个
不好的手机横方向能放下的像素点400个,那么一个像素点在坏的手机的大小是好手机两倍
dp/dip: device-independent pixels(设备无关像素)
换算的方法有三种:
1dp = (dpi / 160) px
1dp = density px 160–>1px 120–>0.75 320–>2px
1px = 1/density dp
sp:scaled pixels(可缩放像素)
与dp类似,但是可以根据用户的字体大小首选项进行缩放
注意: Android在运行时会自动将dp/dip/sp为单位的尺寸转换为像素单位的值
dp与px的比较?
以px为单位的长度, 在差手机上会变大, 在好手机上变小
以dp为单位则不会变化
dp与sp的比较?
用户可以在系统设置中设置文本的大小
如果字体大小使用sp为单位, 设置有效果
如果字体大小使用dp为单位, 设置没有效果
在布局文件视图的宽高尽量用match_parent/wrap_content
如果必须指定特定值, 使用dp/dip做单位
文本大小使用sp做单位