简单理解 Java 反射机制

根据一个对象获得一个类

1
2
String str = "adb";
Class class = str.getClass();

根据一个字符串获得一个类

字符串需要包括完整的包名和类名。

1
2
3
4
5
Class class = Class.forName("java.lang.String");
Class class2 = Class.forName("android.widget.Button");

// 获得对象的父类型
Class class3 = class2.getSuperClass();

Read More

理解 JNI

2020.06.15 更新

JNI 概述

JNI(Java Native Interface),意为 Java 本地调用,是连接 Java 和 native 的桥梁。

JNI 推出的原因:

  1. Java 的平台无关性不能迁移到虚拟机上, Java 虚拟机是使用 native 编写的,虚拟机运行在具体的平台上(Linux、Windows等),由于平台的特性,所以虚拟机无法实现平台无关性。Java 使用 JNI 技术可以作为桥梁,可以实现 Java 调用虚拟机的 native 层,实现了Java 的平台无关性。
  2. 执行效率和速度。

JNI 之 Java 层操作

Java 层主要有两个关键:

  1. 加载 native 动态库
  2. 声明 Java 的 native 方法

此方式为动态加载注册方式,即在运行时加载 jni 库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MediaScanner implements AutoCloseable {
static {
System.loadLibrary("media_jni");// 加载 so 库
native_init();//调用 native 方法
}
...
// 在 Java 中声明 native 方法
private static native final void native_init();
private native final void native_setup();
private native final void native_finalize();

...

}

Read More

面向对象思想的思考

OOP (Object Oriented Programming) 面向对象程序设计

  1. OOP 强调的是数据。OOP 不像面向过程编程那样,试图使问题满足语言的过程性方法,而是试图让语言满足问题的要求。前者是让编程语言去 实现问题的解决方法,即以算法为主,而后者是让编程语言去 实现问题中的主体
  2. OOP 程序设计方法首先设计类,它准确的表示程序要处理的东西,然后设计一个使用这些类的对象的程序,从低级组织(如类)到高级组织的处理过程叫做 自下而上编程
  3. 设计一个有用、可靠的类是十分重要的任务,一个优秀的类可以极大的减轻编程的难度及工作量。

Java Basic Four

1. 概要

  1. 内部类为什么会出现
  2. 内部类的调用
  3. 内部类与外部类访问成员变量的不同
  4. 静态内部类和非静态内部类

1.1 为什么使用内部类

  1. 内部类提供了 更好的封装,可以把内部类的细节隐藏在外部类中,对同一个包中的其他类不可见。

  2. 内部类可以访问外部类的数据 (包括私有变量),但是外部类不可以访问内部类的私有变量。因为内部类持有外部类的引用。

    内部类为外部类的成员,成员之间可以互相访问,这符合 Java 对象思想,但是外部类不可以访问内部类的私有数据。

    真实原因是 JVM 在编译时会将外部类和内部类便以为两个类 – OutterClass.class、OutterClass$InnerClass,OutterClass$InnerClass 对象持有 OutterClass 类的引用

  3. 可以使用匿名内部类创建访问一次的类,十分方便。

2. 非静态内部类

例子 :

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
28
29
30
31
public class OutClass {

private int num = 1;
private int num2 = 3;

private class InnerClass {

private int num = 2;

private void method() {
System.out.println("innerclass method");
System.out.println("innerclass method inner num " + num);
System.out.println("innerclass method inner num " + this.num);
System.out.println("innerclass method out num " + OutClass.this.num);
System.out.println("innerclass method out num2 " + num2);
}

}

public static void main(String[] args) {
OutClass outclass = new OutClass();
System.out.println("main "+ outclass.num);
outclass.test();
}

private void test() {
InnerClass inner = new InnerClass();
inner.method();
System.out.println("outclass test");
}
}

Read More

Vim 基本使用

1、插入命令

命令 作用
a 在光标所在字符插入
A 在光标所在行尾插入
i 在光标所在字符插入
I 在光标所在行首插入
o 在光标插入行
O 在光标插入行

2、定位命令

命令 作用
:set nu 设置行号
:set nonu 取消行号
gg 到第一行
G 到最后一行
nG 到第n行
:n 到第n行
$ 移至行尾
0 移至行首

Read More

IntentFilter匹配规则

IntentFilter 中的过滤信息包括 action、category、data,为了匹配过滤列表需要同时匹配 action、category、data ,否则匹配失败。

action 匹配规则

action 是一个字符串,系统定义了一些 action,用户自己也可以定义 action。

Read More

Android编程中的一些概念(Wiki)

1. 编译器

编译器(compiler) ,是一种 应用程序,它会将某种编程语言写成的源代码(原始语言),转换为另外一种编程语言(目标语言),比如将 C 文件编程称为二进制文件。

它的主要目的是将人编写、维护的高级计算机语言所写出的 源代码程序,翻译为计算机能解读、运行的低价 机器语言 的程序,也就是 可执行文件

Read More

常用的 Gradle 命令

gradlew -q app:dependencies

出现依赖库版本冲突,一般会包如下错:

1
All com.android.support libraries must use the exact same version specification (mixing versions can lead to runtime crashes). Found versions 28.0.0, 25.2.0. Examples include com.android.support:animated-vector-drawable:28.0.0 and com.android.support:support-media-compat:25.2.

一般出现这种错的原因是自己依赖的库与其他依赖的库所依赖的库为同一个 group 的库,但是版本不同。

使用 ./gradlew -q app:dependencies 可以看到自己项目依赖库的层级关系:

解决:使用 exclude 排除相应的库

1
2
3
4
api 'com.android.support:appcompat-v7:28.0.0'
api ("com.alibaba:arouter-api:1.4.0"){
exclude group: 'com.android.support',module:'support-v4'
}

打包 jar 、aar

概念

aar:(Android Archive) 是一个 Android 库项目的二进制归档文件,里面不仅包含工程代码还包括工程资源文件,大部分的 aar 文件包括:AndroidManifest.xml,classes.jar,res,R.txt。

jar:只包含了 class 文件和清单文件,不包含资源文件。

如果需要资源文件,那么以 aar 的形式引入到工程,反之使用 jar。

打包 aar、jar

如果将 Application 打包为 aar,做以下更改:

  1. apply plugin: 'com.android.application' 改为 apply plugin: 'com.android.library'
  2. 去掉 applicationId
  3. 项目根目录执行 ./gradlew assembleRelease,就可以在相应的目录(build/output/aar)下看到生成的 aar,在 build/intermediates/packed-classes 中看到相应的 jar 包。

可以使用新建 gradle task 可以将生成的 jar 包直接复制到 libs 下,并完成构建。

1
2
3
4
5
6
7
8
9
task copyJar(type: Copy) {
def name = project.name //Library名称
delete 'libs/' + name + '.jar' //删除之前的旧jar包
from('build/intermediates/packaged-classes/release/') //从这个目录下取出默认jar包
into('libs/') //将jar包输出到指定目录下
include('classes.jar')
rename('classes.jar', name + '.jar') //自定义jar包的名字
}
copyJar.dependsOn(build)

自定义 jar