Android开发

目录

Java

开发环境

环境配置:

  1. JDK下载

https://www.oracle.com/java/technologies/downloads/

  1. 环境变量
1
2
3
4
5
6
7
8
9
JAVA_HOME
//这里写jdk的安装路径
//如:C:\Program Files\Java\jdk1.8.0_151

Path:
%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;

CLASSPATH:
.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;

编译运行Java程序:

代码示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
//包名
//开头-项目名称-功能
//公司用com, 个人用org, 官方用java开头
//包里面的以点分割的字段, 分别对应一个文件夹名
package org.hello.main;

import org.hello.math.Math;

public class Hello {

 public static void main(String[] args) {
        System.out.println("1 + 2 = " + Math.add(1, 2));
 }
}
1
2
3
4
5
6
7
8
package org.hello.math;

public class Math {
    public static int add(int n1, int n2)
    {
     return n1 + n2;
    }
}
注意
  • 文件名和类名一致
  • 一个类对应一个文件
  • 包里面的以点分割的字段,分别对应一个文件夹名

编译运行:

应用的示例代码为上面的

  1. 文件夹结构

文件夹结构1

文件夹结构2

  1. 编译
1
javac -cp C:\Users\XiaLuoHun\Desktop\LuoJavaTest Hello.java

编译1

编译2

  1. 运行
1
java org.hello.main.Hello

java运行

Java编译运行.rar

Eclipse导出Java工程:

Eclipse导出Java工程1

Eclipse导出Java工程2

运行Java的可执行Jar文件:

运行Java的可执行Jar文件

数据类型

Java数据类型

关键字

final:

1
2
//类似于C++中的const
final int n = 1;

运算符:

1
2
3
int n = 1;
n >>= 1;//Java中都是有符号数的, 右移补符号位
n >>>= 1;//高位补0

abstract, extends:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
public abstract class IShape{
    //抽象方法
    abstract public void fun1();
    //非抽象方法
    public void fun2(){

    }
}

//Java无多重继承
public class LuoLine extends IShape{

    @Override
    public void fun1() {

    }
}

interface, implements:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
//接口类1
public interface Interface1 {
    public void fun1();
}

//接口类2
public interface Interface2 {
    public void fun2();
}

//多重继承也是有需求的,如:两个基类都是接口类的情况下
public class LuoTest implements Interface1, Interface2{
    @Override
    public void fun1() {

    }

    @Override
    public void fun2() {
    }
}

包装类

模板:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
public class LuoList<T>{
    public void push_back(T e){

    }
}

//Java中的模板是假的模板,没有编译预处理的说法,即不存在替换代码
//上述代码编译后为下面的代码
public class LuoList{
    public void push_back(Object e){

    }
}

//Java中的泛型编程,只能传对象进去,且这个对象是Object的派生类
//我们通常写的一个类,编译器默认添加extend Object, 即默认是Object的派生类
//Java为每个基本类型都生成了一个类对象
//int -> Integer, double -> Double, float -> Float, short -> Short
LuoList<Integer> LuoAry = new LuoList<Integer>();
LuoAry.push_back(1);//等价于LuoAry.push_back(new Integer(1));
LuoAry.push_back(2);

Java中的基本数据类型没有方法和属性, 而包装类就是为了让这些拥有方法和属性,实现对象化交互.

Java包装类

1
2
int n = Integer.parseInt("100");
float f = Float.parseFloat("10.88");

流程控制语句

跳出多重循环:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
//Java中没有goto, 但可以使用break Label
//下面语句的意思是,当j == 3时, 跳出下面的两层循环, 打印Hello Java
Label1:
for (int i = 0; i < 3; i++){
    for (int j = 1; j < 4; j++){
        System.out.println(i * j);
        if ( j == 3){
            break Label1;
        }
    }
}
System.out.println("Hello Java");

内部类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Hello{
    private int m_nData1 = 1;

    //当内部类不是静态的时候, 他有两个this指针
    public class LuoHello {
        private int m_nData2 = 100;

        public void Luofun() {
            //因为有两个this指针, 这里可以访问m_nData1成员
            m_nData1 = 10;
            System.out.println("LuoHello m_nData1 = " + m_nData1 + " m_nData2 = " + m_nData2);
        }
    }

    private void fun(){
        System.out.println("Hello m_nData1 = " + m_nData1);

        //new LuoHello这个内部类的时候, 偷偷将Hello的this指针传了进去
        LuoHello Luo = new LuoHello();
        Luo.Luofun();
    }

    public static void main(String[] args) {
        Hello Hun = new Hello();
        Hun.fun();
    }
}

集合类的使用

List Set Map

库的使用

百度搜索 java api, 可看到官方网址: https://docs.oracle.com/javase/8/docs/api/

Android

概述

Android网站

体系架构

Android体系架构

  • 最底层,Linux内核.
  • HAL层,硬件抽象层,为了不修改Linux代码,因为一旦修改了,就必须开源,Linux开源协议是gpl协议.
  • Lib库层,C语言写的,类似于Windows的API.
  • ART虚拟机,Dalvik虚拟机已经淘汰了,从Android5.0开始使用ART虚拟机.
  • Java Api框架,Java代码写的,让程序员可以用Java调用C.
  • 应用层,提供各种各样的控件,直接调用.

Jvm

编译方式:.java文件->.class文件->.jar文件

架构:基于堆栈

Dvm

编译方式:.java文件->.class文件->.dex文件

.dex文件:压缩版的.jar文件,将所有的.class文件合并为一个.dex文件,减少冗余 如:两个class文件中有相同的字符串,这样合并为.dex文件时 相同的字符串只保留了一份.

架构:基于寄存器

AndroidStudio

Android开发者网站

安装SDK

安装SDK1

安装SDK2

安装虚拟机

安装虚拟机

开启虚拟机开发者模式

  1. 在设置中,一直点击版本号.
  2. 在开发者模式中,开启USB调试.

快捷键

重命名:

Shift + F6

注释:

Ctrl + Shift + /

代码格式化:

Ctrl + Alt + L

所选代码封装为方法:

Ctrl + Alt + M

后退:

Ctrl + Alt + 向左箭头

前进:

Ctrl + Alt + 向右箭头

快速代码生成:

Alt + Insert

方法参数提示:

Ctrl + P

查看类方法:

Ctrl + F12

类结构窗口:

Alt + 7

类继承图:

Ctrl + H

APK的生成

APK结构

APK结构

res目录中的xml文件为二进制格式,称为AXML

SDK目录工具

SDK目录工具

aapt.exe

res(编译前的资源)-> aapt.exe(aapt2.exe) -> resources.arsc + res(AXML) + AndroidManifest.xml.

可将编译前的资源文件转换成APK文件中的资源文件,也可将APK文件中的资源文件转换成编译前的资源文件.

javac.exe

.java文件->javac.exe->.class文件

dx.bat(d8.bat)

将编译前的*.class文件->dx.bat(d8.bat)->.dex文件 (老版是用dx.bat, 新版是用d8.bat)

zip压缩算法打包

res(AXML) + AndroidManifest.xml + .dex + resources.arsc -> .apk

zipalign.exe

此工具,与dx.bat同目录. 上述生成的.apk文件,需经此工具进行对齐(AndroidStudio生成的apk文件自动对齐),目的是要确保所有未压缩数据的开头均相对于文件开头部分执行特定的对齐.

apksigner.bat(数字签名 RSA)

此工具,与dx.bat同目录. 对上述apk文件,进行数字签名,系统才会安装此apk. 签名在apk文件解压缩后的META-INF文件夹中.

apk签名

AS签名1

AS签名2

V1签名机制只校验了现有的文件,没有校验整个apk文件,这就导致了,可以通过向apk中添加文件达到劫持注入的目的.

签名后的文件,在工程根目录中的app目录下的release目录下.

本地化应用

中文系统,界面就显示中文;英文系统,界面就显示英文.

  1. 向strings.xml添加字符串

本地化应用1

  1. 修改activity_main.xml中的字符串引用为strings.xml中的

本地化应用2

  1. 复制values文件,添加后缀zh

本地化应用3

  1. 修改values-zh中的strings.xml中的内容为中文

本地化应用4

Activity

提供窗口供应用在其中绘制界面,此窗口通常会填满屏幕,但也可能比屏幕小,并浮动在其他窗口上面.

新建一个Activity

  1. 新建一个类

新建一个Activity1

  1. 在AndroidManifest.xml文件中说明

新建一个Activity2

快速创建Activity

快速创建Activity

启动新界面

启动新界面

生命周期

Activity生命周期

在Avtivity中重写上述虚函数:

Activity生命周期2

进程和应用生命周期

进程和应用生命周期

布局

布局概念1

布局概念2

AS新建布局

AS新建布局

设置布局

AS设置布局

绝对布局

指明子组件的绝对位置,对于不同尺寸的手机来说,适配性较差.

绝对布局1

绝对布局2

1
2
3
4
 <!--  与父窗口同宽   -->
android:layout_width="match_parent"
 <!--  与文本同高   -->
android:layout_height="wrap_content"

线性布局

用于使所有子视图在单个方向(垂直或水平)保持对齐.

线性布局1

线性布局2

1
2
3
4
5
6
7
 <!--  指定布局方向(垂直或者水平)   -->
android:orientation="horizontal"
<!--      
权重,上图中两控件宽度为0,一个权重为1,一个权重为3,
表示将父窗口宽度划分为4份,一个占1份,一个占3份
-->
android:layout_weight

相对布局

不能设置权重,目前AS支持很差,已被约束布局取代.

帧布局

一个控件可以覆盖在另一个控件上.

应用场景:切换界面.

表格布局

用的很少,可以用线性布局来做.

约束布局

主流布局,在相对布局的基础上加上权重.

查看别人的布局

查看别人的布局1

要确保AS和模拟器连接上,方可在下方选择进程,查看布局.

查看别人的布局2

控件相关

华丽界面示例

  1. 创建一个xml文件.

华丽界面示例1

华丽界面示例2

  1. 写下按钮被按下和未被按下所应用的图片.

华丽界面示例3

  1. 修改button的背景.

华丽界面示例4

华丽界面示例5

  1. button修改完成.

华丽界面示例6

模拟Android系统操作xml文件

模拟Android系统操作xml文件1

模拟Android系统操作xml文件2

TextView

TextView

EditText

EditText

Button

Button

按钮消息响应:

  1. 自定义一个事件监听类.

按钮消息响应1

  1. 按钮注册监听.

按钮消息响应2

CheckBox

CheckBox

RadioButton

RadioButton

列表组件

数据适配器

数据适配器

上图展示了数据源、适配器、列表控件之间的关系. 我们知道,数据源是各种各样的,而ListView所展示数据的格式则是有一定的要求的. 数据适配器正是建立了数据源与ListView之间的适配.

常用适配器

ArrayAdapter:

只能操作一个控件,如下述中在操作了TextView控件后,不能修改图片控件.

  1. 新建一个布局文件, 记录每行的UI.

ArrayAdapter1

  1. 设置.

ArrayAdapter2

ArrayAdapter3

SimpleAdapter:

  1. 新建一个布局文件.

SimpleAdapter1

  1. 设置

SimpleAdapter2

SimpleAdapter3

自定义适配器

不用考虑通用性.

示例:

  1. 新建一个布局文件.

自定义适配器1

  1. 写一个类,继承BaseAdapter.

自定义适配器2

调用:

自定义适配器3

源代码

控件相关.rar

菜单

选项菜单

  1. 新建一个menu文件夹.

选项菜单1

选项菜单2

  1. 新建一个menu Xml文件.

选项菜单3

选项菜单4

  1. 重写onCreateOptionsMenu函数,产生菜单.

选项菜单5

  1. 重写onOptionsItemSelected函数,处理菜单消息.

选项菜单6

上下文菜单

  1. 存放菜单相关信息,同上.

上下文菜单1

  1. 注册菜单(示例给ListView注册菜单).

上下文菜单2

上下文菜单3

  1. 重写onCreateContextMenu函数,产生菜单.

上下文菜单4

  1. 重写onContextItemSelected函数,处理菜单消息.

上下文菜单5

源代码

事件处理模型.rar

提示信息

提示信息1

提示信息2

消息对话框

消息对话框1

消息对话框2

事件处理模型

基于多态机制

使用场景:

触摸,按键.

示例:

重写虚函数.

基于多态机制

基于监听接口

使用场景:

按钮.

监听过程:

监听过程

事件接口:

事件接口

示例:

外部类(基本不用):

  1. 新建一个类实现监听接口.

外部类(基本不用)1

  1. 给按钮注册监听器.

外部类(基本不用)2

内部类(常用):

内部类(常用)

当按钮较多时,直接由Activity实现监听接口:

由Activity实现监听接口

匿名类(常用):

跟内部类没有区别, 匿名类会由编译器自动生成为内部类, 生成的类名通常为外部类名$1 外部类名$2…

匿名类(常用)1

匿名类(常用)2

基于系统设置

Configuration类专门用于描述手机设备上的配置信息.

基于系统设置

基于消息循环

Android中只有主线程可操作UI,其他线程操作UI会崩,考虑同步的话会降低效率.

基于消息循环

自己创建消息循环:

在Android开发者网站搜索Looper类.

自己创建消息循环

源代码

事件处理模型.rar

Intent(意图)

3个信息

  • 行为, 指定要执行的通用操作(例如,查看或选取)的字符串.
  • 数据.
  • 类别,一个包含应处理Intent组件类型的附加信息的字符串.

注册意图

注册意图

Activity中的意图不能只给行为,也要给类别.

显示Intent

如打车,明确告诉从哪条路走,无跨进程概念.

显示Intent示例

用Intent来传输数据:

这里启动另一个Activity,将用户名和密码传过去(即便跨进程,也可以将数据传过去),然后另一个Activity将真正的密码传回来,最后取回传回来的数据并显示.

  1. 启动一个Activity并传数据.

用Intent来传输数据1

  1. 另一个Activity接收数据.

用Intent来传输数据2

  1. 接收Activity销毁后传回来的数据.

用Intent来传输数据3

隐式Intent

如点外卖,不用关心外卖是如何送到的,可跨进程.

  1. 在Manifest说明权限.

隐式Intent1

  1. 请求权限.

隐式Intent2

  1. 获取请求权限结果.

隐式Intent3

启动别人的Activity:

  • 以自己写的为例.

启动别人的Activity1

启动别人的Activity2

  • 设置闹铃.

启动别人的Activity3

  • 打电话.

启动别人的Activity4

源代码

Intent(意图).rar

服务

是一种可在后台执行长时间运行操作而不提供界面的应用组件.

创建服务

  1. 创建一个类,继承Service.

创建服务1

  1. 注册服务.

创建服务2

  1. 启动与停止服务.

创建服务3

本进程和服务进行通讯

  1. 创建一个内部类,继承Binder.

本进程和服务进行通讯1

  1. 在onBind函数中,返回Binder对象.

本进程和服务进行通讯2

  1. 创建一个ServiceConnection对象.

本进程和服务进行通讯3

  1. 绑定服务.

本进程和服务进行通讯4

注意
服务默认运行在主线程中.

服务注意

跨进程操作服务

在高版本的Android系统中,自建服务的跨进程操作,只能在创建服务的子进程中进行操作,只有系统服务,所有进程可操作.

  • 将服务放在创建服务的子进程中

将服务放在创建服务的子进程中

  • 跨进程启动和停止服务

跨进程启动和停止服务

跨进程通讯

AIDL:

利用内核,进行进程间的通讯.

AIDL

使用AIDL创建绑定服务:

  1. 创建.aidl文件.

使用AIDL创建绑定服务1

  1. 在.aidl文件中声明接口.

使用AIDL创建绑定服务2

此时编译整个工程,会发现编译器帮我们创建了一个ICount的接口.

使用AIDL创建绑定服务3

  1. 实现声明的接口.

使用AIDL创建绑定服务4

  1. 在另一个进程中,重写服务连接函数.

若两个工程,需要把aidl文件拷贝过去.

使用AIDL创建绑定服务5

  1. 绑定服务,解绑服务,与服务进行通讯.

使用AIDL创建绑定服务6

前台服务

UI放在通知栏.

  1. 在Manifest文件声明权限.

前台服务1

  1. 创建渠道ID.

前台服务2

  1. 创建前台服务.

前台服务3

源代码

服务1.rar

服务2.rar

广播

广播概览

广播是一种状态的通知,例如我想知道手机网络状态变化,此时我只要注册一个网络状态变化的广播,当系统网络状态发生变化的时候,系统就会发广播,我就可以收到.

广播电台

有序广播

接收广播的时候按优先级,优先级高的先接收到广播,可选择是否中断广播,让后面优先级低的接收不到广播.

无序广播

接收广播的时候无优先级,谁注册了都可以接收到此广播.

本地广播

效率高,不需要跨应用发送广播,可选本地广播.

广播电台示例

广播接收者

  1. 创建一个类继承BroadcastReceiver

广播接收者1

广播接收者2

  1. 注册广播

静态注册:

在Manifest文件中进行说明,高版本目前不允许(即便静态注册了,也不会收到广播), 当然也有例外.

为了兼容老版本,在高版本中静态注册会变成动态注册,但必须软件运行起来方可接收到广播.

静态注册广播1

静态注册广播2

动态注册:

动态注册广播

发送带权限的广播

发送带权限的广播

接收系统广播示例

系统常见广播:

系统常见广播

以接收系统短信广播为例:

  1. Manifest文件中说明权限.

接收系统短信广播1

  1. 新建一个类继承BroadcastReceiver.

接收系统广播示例2

  1. 注册短信广播.

需要应用有接收短信的权限,方可接收到短信广播.

接收系统广播示例3

源代码

广播.rar

文件

Android中每个应用有自己的私有空间,其他应用不允许访问.

文件概述

文件存储

配置文件(保存键值对数据)

使用 SharedPreferences API.

  1. 创建配置文件并写内容.

配置文件1

创建的文件,在根目录的data/data/包名目录中.

配置文件2

  1. 读取配置文件.

配置文件3

自定义文件格式

使用Java中的文件流:

自定义文件格式1

示例:

自定义文件格式2

创建的文件,在根目录的data/data/包名目录中.

自定义文件格式3

共享存储

Android中SD卡内容,所有应用共享.

  1. 说明权限.

共享存储1

  1. 操作示例.

共享存储2

[Android 10.0后创建文件createNewFile()和创建文件夹mkdirs()均失败解决方案.mhtml](Android 10.0后创建文件createNewFile()和创建文件夹mkdirs()均失败解决方案.mhtml)

源代码

文件.rar

数据库

创建数据库和表:

数据库1

增:

数据库2

删:

数据库3

改:

数据库4

查:

数据库5

注意
使用Android封装好的SQL操作,可以防止SQL注入.
数据库

内容提供程序

内容提供程序概述

内容提供者

  1. 创建一个类继承ContentProvider, 实现增删改查接口.

内容提供者1

  1. 在Manifest文件中注册内容提供者.

内容提供者2

内容提供者

内容接收者

拿上述内容提供者的数据:

增:

拿上述内容提供者的数据1

删:

拿上述内容提供者的数据2

改:

拿上述内容提供者的数据3

查:

拿上述内容提供者的数据4

内容接收者

拿系统内容提供者的数据:

拿联系人信息:

  1. 在Manifest文件中说明.

拿联系人信息1

  1. 示例.

拿联系人信息2

拿联系人信息

拿短信信息:

  1. 在Manifest文件中说明.

拿短信信息1

  1. 示例.

拿短信信息2

拿短信信息

内容观察者

向系统注册一个内容观察者,当内容发生了变化,就会收到通知.

  1. 在Manifest文件中说明.

内容观察者1

  1. 写一个类继承ContentObserver,重写onChange函数.

内容观察者2

  1. 注册内容观察者.

内容观察者3

内容观察者

Fragment

Activity中放Fragment,Fragment中放布局,可以用来切换视图.

Fragment概述

  1. 新建一个布局文件.

Fragment1

  1. 写一个类继承Fragment,重写onCreateView函数.

Fragment2

  • 静态注册.

Fragment3

  • 动态注册.

Fragment4

源代码

Fragment.rar

功能操作

遍历系统安装的软件

管理器:

遍历系统安装的软件1

示例:

通过包管理器,我们可以知道系统安装的软件.

遍历系统安装的软件2

启动应用

启动应用

卸载应用

卸载应用

遍历进程

遍历进程

流量查看

低版本用TrafficStats 不准确,高版本用NetworkStatsManager.

监控电话

监控电话

屏幕截图

Android5.0以后,加入了屏幕采集的API.

屏幕截图概述

示例:

屏幕截图.rar

无视权限,截图:

在Android系统的system/bin目录下有screencap这个程序,这就是用来截图的.只有当uid = shell或者uid = root才可以调screencap来截图.

shell权限,就是cmd 执行adb shell.

获取Root权限:

未root的手机,system/bin目录下没有su这个程序,所谓的root就是在system/bin目录下放su这个程序.

获取Root权限

模拟键盘 鼠标 触摸等:

在system/bin目录下 有个input程序.

网络编程

使用Java的API

使用Java的API

PC端为Server, Android端为Client.

Server:

Java中的收发数据跟读写文件一样,一切都是流.

网络编程1

网络编程Server.rar

Client:

网络编程2

网络编程3

网络编程Client.rar

注意

Android为Client, PC为Server时, 若通过回环地址连接,Android端需填 10.0.2.2

Android为Server, PC为Client时, 若通过回环地址连接,PC端需要做端口映射.

在Android虚拟机打开的情况下,通过adb命令 adb forward tcp:port tcp:port

Android端执行CMD命令

Android端执行CMD命令


相关内容

0%