1. adb 쉘
adb 셸 아래에 있는 몇 가지 일반적인 명령줄 도구:
pm : 패키지 관리자인 PackageManager는 애플리케이션의 설치, 제거, 쿼리 및 기타 관련 작업을 관리하는 데 사용됩니다.
pm install …//
pm uninstall …//
pm 패키지 목록 표시//장치에 설치된 애플리케이션
pm dump…//패키지 이름, 버전 번호, 권한 등과 같은 애플리케이션 세부정보 가져오기
am : 장치 활동 및 애플리케이션 상태를 관리하는 데 사용되는 활동 관리자, 활동 관리자
am start…//
am stop…//
am force-stop…//
am Broadcast //브로드캐스트 보내기 adb shell am Broadcast -a com .example.myapp.CUSTOM_ACTION --es message "Hello, World!" ——-매개변수는 브로드캐스트 작업(Action)을 지정하고, -es 매개변수는 추가 문자열 값을 추가하는 데 사용되며 키는 message이고 값은 " 안녕, 월드!”
adb: Android 디버그 브리지는 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로 변경합니다.
2.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")
3. 자산 디렉터리의 파일을 읽습니다.
AssetsManager 객체
1.컨텍스트
//获取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.자원
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()
4. 자바 스파이
핵심 아이디어: 분리된
SPI(Service Provider Interface)는 JDK에 내장된 서비스 검색 메커니즘 으로 , 프레임워크 확장 및 구성 요소 교체를 활성화하는 데 사용할 수 있습니다.
1. 인터페이스와 구현 클래스 정의
public interface IFather{
...}
public class Son implements IFather{
...}
2. 리소스 디렉터리 아래에 새 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개와 RetentionPolicy 1개가 연결되어 있습니다.
1 주석은 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?,
) {
...}
6. 제네릭
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)만 가능합니다.
7. 모노 응답 프로그래밍
비동기 프로그래밍, 처리 시간이 많이 걸리는 논리. mono는 0개 또는 1개의 요소를 포함하는 비동기 시퀀스를 처리하는 데 사용됩니다.
val mono = Mono.fromCallable{
......//耗时逻辑
}
mono.subscribe{
result ->
Log.d(TAG,"....")
}//只有subscribe这里订阅了,fromCallable里的耗时逻辑才会执行
val mono = Mono.just{
...
}
同样需要订阅
//让耗时逻辑在子线程中执行
mono.subscribeOn(Schedulers.Parallel())
mono.subscribeOn(Schedulers.boundedElastic())