一、adb shell
adb shell下一些常用命令行工具:
pm:PackageManager,包管理器,用于管理应用程序的安装、卸载、查询和更多相关操作。
pm install …//
pm uninstall …//
pm list packages//设备上已安装的应用程序
pm dump …//获取应用程序的详细信息,如包名、版本号、权限等
am:Activity Manager,活动管理器,用于管理设备上的活动和应用程序的状态
am start …//
am stop …//
am force-stop …//
am broadcast //发送广播 adb shell am broadcast -a com.example.myapp.CUSTOM_ACTION --es message “Hello, World!” ——-a 参数指定广播的动作(Action),–es 参数用于添加一个额外的字符串值,键为 message,值为 “Hello, World!”
adb:Android 调试桥(Android Debug Bridge)是与 Android 设备通信的主要命令行工具。它提供了与设备进行文件传输、调试、安装应用程序和执行其他操作的功能。
ls:ls 命令用于列出目录中的文件和子目录。例如,ls /sdcard 可以列出设备存储卡(SD 卡)上的文件和目录。
cd:cd 命令用于更改当前工作目录。例如,cd /sdcard 可以将当前目录切换到设备存储卡。
mkdir:mkdir 命令用于创建新的目录。例如,mkdir /sdcard/new_directory 可以在设备存储卡上创建一个名为 “new_directory” 的新目录。
cp:cp 命令用于复制文件或目录。例如,cp /sdcard/file.txt /sdcard/backup/file.txt 可以将名为 “file.txt” 的文件复制到名为 “backup” 的目录下。
mv:mv 命令用于移动文件或目录,也可用于重命名文件或目录。例如,mv /sdcard/file.txt /sdcard/new_location/file_new.txt 可以将文件移动到新位置并重命名为 “file_new.txt”。
rm:rm 命令用于删除文件或目录。例如,rm /sdcard/file.txt 可以删除名为 “file.txt” 的文件,rm -f 删除文件夹目录
cat:cat 命令用于显示文件的内容。例如,cat /sdcard/file.txt 可以将文件的内容打印到命令行界面上。
chmod:chmod 命令用于更改文件或目录的权限。例如,chmod 755 /sdcard/file.txt 可以将文件的权限更改为 755。
二、json
解析json数据时可以使用GSON(Google提供的一个开源JSON库),Gson 可以将 Java 对象转换为 JSON 字符串,也可以将 JSON 字符串转换为 Java 对象。Gson 提供了更高级的功能和灵活性,例如支持自定义序列化和反序列化规则、处理复杂的对象关系、日期格式化等。
plugins {
id 'kotlin-parcelize'
}
依赖:
implementation "com.google.code.gson:gson:2.9.1"
序列化解析:
@Parcelize
class ParsingObject(
@SerializedName("event_code")//统一编码格式,将json里的下划线转化为驼峰格式
val eventCode: Int = 10501,
@SerializedName("event_code")
val eventValue: Int,
val event: String = "DEFAULT_VALUE",//默认值
val params: FlightParams
) : Parcelable
jsonString
val gson = Gson()
val obj = gson.formJson<ParsingObject>(jsonString, ParsingObject::class.java)
然后解析相应对象即可
json内容是一个list
val info = gson.fromJson(jsonString, Array<ParsingObject>::class.java).toList()
当json内有pair对时,pair对数量未知,且value类型未知
"params":{
"key1":20,
"key2":"value",
"key3":true
}
@Parcelize
class ParseObject(val params : Map<String, @RawValue Any>) : Parcelable
jsonObject解析:
//根据相应特征字段名获取
val jsonObject = JSONObject(jsonStr)
val jsonArray = jsonObject.getJSONArray("list")
val obj = jsonArray.getJSONObject(0)
val cityObj = obj.getJSONObject("cityInfo")
三、读取assets目录中的文件
AssetsManager对象
1.context
//获取AssetManager对象
val assetManager = context.assets
//InputStream 流
val inputStream: InputStream = assetManager.open("filename.txt")
//BufferedReader逐行读取
val reader = BufferedReader(InputStreamReader(inputStream))
var line: String?
while (reader.readLine().also {
line = it } != null) {
// 处理每一行的内容
}
//关闭
reader.close()
inputStream.close()
2.resources
val assetManager = resources.assets
val inputStream: InputStream = assetManager.open("filename.txt")
3.Kotlin扩展函数
val assetManager = context.assets
val inputStream: InputStream = assetManager.open("filename.txt")
fun InputStream.readTextAndClose(charset: Charset = Charsets.UTF_8): String {
return this.bufferedReader(charset).use {
it.readText() }
}
val text: String = inputStream.readTextAndClose()
四、java spi
核心思想:解耦
SPI(Service Provider Interface),是JDK内置的一种 服务提供发现机制,可以用来启用框架扩展和替换组件。
1.定义接口及其实现类
public interface IFather{
...}
public class Son implements IFather{
...}
2.在resources目录下新建META-INF/services目录
在services目录下新建文件,文件名为接口类的目录,文件内容为要实现的类。
文件名:com.example.IFather
文件内容:com.example.Son
3.加载
ServiceLoader<IFather> s = ServiceLoader.load(IFather.class);
Iterator<IFather> it = s.iterator();
while(it.hasNext()) {
IFather c = it.next();
...
}
4.实现类必须携带一个不带参数的构造函数
五、Annotation
1 个 Annotation 和 1 个 RetentionPolicy 关联。
1 个 Annotation 和 1~n 个 ElementType 关联。
Annotation 有许多实现类,包括:Deprecated, Documented, Inherited, Override 等等
package java.lang.annotation;
public interface Annotation {
boolean equals(Object obj);
int hashCode();
String toString();
Class<? extends Annotation> annotationType();
}
package java.lang.annotation;
public enum ElementType {
TYPE, /* 类、接口(包括注释类型)或枚举声明 */
FIELD, /* 字段声明(包括枚举常量) */
METHOD, /* 方法声明 */
PARAMETER, /* 参数声明 */
CONSTRUCTOR, /* 构造方法声明 */
LOCAL_VARIABLE, /* 局部变量声明 */
ANNOTATION_TYPE, /* 注释类型声明 */
PACKAGE /* 包声明 */
}
@Target(ElementType.Type)//若有就表示用于指定的地方,若无则表示可用于任何地方
package java.lang.annotation;
public enum RetentionPolicy {
SOURCE, /* Annotation信息仅存在于编译器处理期间,编译器处理完之后就没有该Annotation信息了 */
CLASS, /* 编译器将Annotation存储于类对应的.class文件中。默认行为 */
RUNTIME /* 编译器将Annotation存储于class文件中,并且可由JVM读入 */
}
@Retention(RetentionPolicy.RUNTIME)//没有RetentionPolicy默认是CLASS
@Deprecated -- @Deprecated 所标注内容,不再被建议使用。
@Override -- @Override 只能标注方法,表示该方法覆盖父类中的方法。
@Documented -- @Documented 所标注内容,可以出现在javadoc中。
@Inherited -- @Inherited只能被用来标注“Annotation类型”,它所标注的Annotation具有继承性。
@Retention -- @Retention只能被用来标注“Annotation类型”,而且它被用来指定Annotation的RetentionPolicy属性。
@Target -- @Target只能被用来标注“Annotation类型”,而且它被用来指定Annotation的ElementType属性。
@SuppressWarnings -- @SuppressWarnings 所标注内容产生的警告,编译器会对这些警告保持静默。
一个示例:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface ServiceFunctionParameters {
String NO_DEFAULT_VALUE = "OPEServiceFunctionParameters_NO_INPUT_PROVIDED";
String description() default "";
String name();
String defaultValue() default NO_DEFAULT_VALUE;
boolean required() default true;
Class<?> type() default String.class;
}
fun addCalendarSchedule(
@ServiceFunctionParameters(
name = "title",
description = "你需要根据该日程主题给拟一个标题"
) title: String?,
@ServiceFunctionParameters(
name = "description",
description = "日程的具体内容"
) description: String?,
@ServiceFunctionParameters(
name = "startTime",
description = "日程开始时间,格式:yyyy-MM-dd HH:mm:ss"
) startTime: String?,
@ServiceFunctionParameters(
name = "endTime",
description = "日程结束时间,格式:yyyy-MM-dd HH:mm:ss"
) endTime: String?,
) {
...}
六、泛型
1.泛型方法
所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前。
每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。
类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符。
泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型,不能是原始类型(像 int、double、char 等)。
public class GenericMethod {
//泛型方法
public static <E> void printArray( E[] inputArray ) {
// 输出数组元素
for ( E element : inputArray ) {
System.out.printf( "%s ", element );
}
System.out.println();
}
public static void main( String args[] ) {
// 创建不同类型数组: Integer, Double 和 Character
Integer[] intArray = {
1, 2, 3, 4, 5 };
Double[] doubleArray = {
1.1, 2.2, 3.3, 4.4 };
Character[] charArray = {
'H', 'E', 'L', 'L', 'O' };
System.out.println( "整型数组元素为:" );
printArray( intArray ); // 传递一个整型数组
System.out.println( "\n双精度型数组元素为:" );
printArray( doubleArray ); // 传递一个双精度型数组
System.out.println( "\n字符型数组元素为:" );
printArray( charArray ); // 传递一个字符型数组
}
}
整型数组元素为:
1 2 3 4 5
双精度型数组元素为:
1.1 2.2 3.3 4.4
字符型数组元素为:
H E L L O
2.泛型类
泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分,和泛型方法一样,泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符,因为他们接受一个或多个参数,这些类被称为参数化的类或参数化的类型。
public class Box<T> {
private T t;
public void add(T t) {
this.t = t;
}
public T get() {
return t;
}
public static void main(String[] args) {
Box<Integer> integerBox = new Box<Integer>();
Box<String> stringBox = new Box<String>();
integerBox.add(new Integer(10));
stringBox.add(new String("测试"));
System.out.printf("整型值为 :%d\n\n", integerBox.get());//整型值为 :10
System.out.printf("字符串为 :%s\n", stringBox.get());//字符串为 :测试
}
}
3.类型通配符
类型通配符一般是使用 ? 代替具体的类型参数
import java.util.*;
public class GenericTest {
public static void main(String[] args) {
List<String> name = new ArrayList<String>();
List<Integer> age = new ArrayList<Integer>();
List<Number> number = new ArrayList<Number>();
name.add("icon");
age.add(18);
number.add(314);
getData(name);//data :icon
getData(age);//data :18
getData(number);//data :314
}
public static void getData(List<?> data) {
System.out.println("data :" + data.get(0));
}
}
类型通配符的上限由 ? extends Class定义,即只能为Class或其子类
import java.util.*;
public class GenericTest {
public static void main(String[] args) {
List<String> name = new ArrayList<String>();
List<Integer> age = new ArrayList<Integer>();
List<Number> number = new ArrayList<Number>();
name.add("icon");
age.add(18);
number.add(314);
//getUperNumber(name);//String非Number的子类
getUperNumber(age);//
getUperNumber(number);//
}
public static void getUperNumber(List<? extends Number> data) {
System.out.println("data :" + data.get(0));
}
}
类型通配符的上限由 ? superClass定义,即只能为Class及其上层父类型,如object
七、Mono响应式编程
异步编程,处理耗时逻辑。mono用于处理包含零个或一个元素的异步序列。
val mono = Mono.fromCallable{
......//耗时逻辑
}
mono.subscribe{
result ->
Log.d(TAG,"....")
}//只有subscribe这里订阅了,fromCallable里的耗时逻辑才会执行
val mono = Mono.just{
...
}
同样需要订阅
//让耗时逻辑在子线程中执行
mono.subscribeOn(Schedulers.Parallel())
mono.subscribeOn(Schedulers.boundedElastic())