加载apk、aar、jar
AS 可以将一个apk,arr,jar 文件导入,加载并执行其中的类
如果apk,arr中包含so库,也会一并加载.
复杂嵌套加载须知
如果您加载的apk中包含arr,arr中包含so 那么需要将arr中的so拷贝一份放在apk的libs中即可正常加载.
传统的jar包无法加载,需要android工具进行Dex化转换.
将apk,arr,jar注入到运行环境
此方法会将apk,arr,jar等文件注入到当前运行环境,注入后可以像使用普通Java类一样直接 import 使用。
from ascript.android import plug
from ascript.android.system import R
# 注入工程res目录下的包
plug.inject(R.res("demo.apk"))
# 注入绝对路径的包
plug.inject("/sdcard/libs/utils.jar")
支持的格式: .apk .jar .dex
特性:
- 注入后可直接用
from/import导入包中的Java类 - 同一个文件重复调用无副作用
- 如果包中含有
.so原生库,也会一并加载
使用案例
- 假如在你的工程res目录下包含 一个 app-release.apk 文件. 且apk中包含 一个Person类
// Java Person类结构
package com.aojoy.plug.testloader;
public class Person {
public static String a = "a_public";
private static String b = "b_private";
public String name;
private int age;
public Person(){}
public Person(String name,int age){
this.age = age;
this.name = name;
}
public String eat(){
return this.name +"吃饭了";
}
public String eat(String what){
return this.name +"吃的是"+what;
}
public static Person create(){
return new Person();
}
public static Person create(String name,int age){
return new Person(name,age);
}
}
- 用 python 注入apk后直接使用 Person 类
from ascript.android.system import R
from ascript.android import plug
from java import jint
# 注入工程res目录下的 app-release.apk
plug.inject(R.res("app-release.apk"))
# 注入后可直接 import apk 中的类
from com.aojoy.plug.testloader import Person
# 创建无参对象
person = Person()
# 创建有参对象 (python传递给java的数字默认是long类型,这里用jint转换)
person = Person("张三", jint(18))
# 访问公共属性
print(person.name) # 张三
# 调用对象方法
print(person.eat()) # 张三吃饭了
print(person.eat("包子")) # 张三吃的是包子
# 访问静态属性
print(Person.a) # a_public
# 调用静态方法
person2 = Person.create("李四", jint(20))
print(person2.eat()) # 李四吃饭了
对比旧方式
注入后无需再使用 Reflect 反射调用,直接 import 即可,代码更简洁、更符合 Python 习惯。
访问私有属性/方法
注入后直接 import 的方式只能访问公共成员。如果需要访问私有属性或方法,仍可配合 Reflect 使用:
from ascript.android import plug
from ascript.android.system import R
from org.joor import Reflect
from java import jint
plug.inject(R.res("app-release.apk"))
from com.aojoy.plug.testloader import Person
person = Person("张三", jint(18))
# 访问私有属性 age
age = Reflect.on(person).field("age").get()
print(age) # 18