目录
1. Android 12编译指令
以前使用make framework -j16或者在framework/base目录下使用mm编译都不会生成framework.jar。
1.1 framework层的编译指令
make -j32 framework-minus-apex
编译通过后,输出路径为
out\target\product\qssi\system\framework\framework.jar
1.2 替换framework.jar
adb root
adb remount
adb shell "rm -rf /system/framework/arm"
adb push framework.jar /system/framework
adb shell sync
adb reboot
1.3 编译frameworks/base/core/res
如果修改frameworks/base/core/res目录下的文件,例如AndroidManifest.xml或者其他资源文件,不需要整编framework层,只需要在该目录下mm单编就可以。
会在out/target/product/qssi/system/framework/framework-res.apk生成framework-res.apk, 把该apk用adb push到设备目录/system/framework/下即可。
2. 编译services
2.1编译指令
在frameworks/base/services目录下执行 mm
或者在android目录下执行
mmm frameworks/base/services -j32
或者
make -j32 services
编译通过后,输出路径为
out\target\product\qssi\system\framework\services.jar
2.2 替换services.jar
adb root
adb remount
adb shell "rm -rf /system/framework/arm"
adb push services.jar /system/framework
adb shell "rm -rf /data/dalvik-cache/arm/system@framework@services.jar@classes.* "
adb shell sync
adb reboot
3. Android 12的API标准规范
3.1 注解的使用
3.1.1 @NonNull和@Nullable
@NonNull:表示返回值、参数或者field不能是null。
@Nullable:表示返回值、参数或者field可以是null。
如果没有标注,则会报异常:Missing nullability on parameter,当编译报这个错误时,根据需要添加这两个注解。
getter/setter的Nullablility必须一致。
3.1.2 @IntDef和@StringDef
用来接受一组有限的int或者String类型的public常量,可以使用这两个注解这个。这个注解通常结合@interface来使用来创建一个新的注解。例如:
public final class Log {
/** @hide */
@IntDef({ASSERT, ERROR, WARN, INFO, DEBUG, VERBOSE})
@Retention(RetentionPolicy.SOURCE)
public @interface Level {}
public static final int VERBOSE = 2;
public static final int DEBUG = 3;
public static final int INFO = 4;
public static final int WARN = 5;
public static final int ERROR = 6;
public static final int ASSERT = 7;
}
建议使用同一的前缀。
/** @hide */
@IntDef(prefix = { “FLAG_” }, value = {
FLAG_USE_LOGO,
FLAG_SHOW_HOME,
FLAG_HOME_AS_UP,
});
@Retention(RetentionPolicy.SOURCE)
public @interface DisplayOptions {}
3.1.3 Listener和Callback的规则
-
当只有一个回调方法且永远不会有其他回调方法时使用Listener,且注册监听和解注册监听的方法必须是add/remove开头,否则Android Lint编译不过。
public interface OnFooListener {
void onFoo();
}
public void addOnFooListener(@NonNull OnFooListener listener) {}
public void removeOnFooListener(@NonNull OnFooListener listener) {}
- 当有多个回调方法时,或者有关联的常量时,应该使用Callback。Callback类可以是一个interface或者abstract class。添加callback和去掉callback应该使用register和unregister开头的方法。
- callback中的方法应该以on-开头。
- 使用MyObjectCallback代替MyObjectObserver。这个是否报错不确定,我是把Listener改为Callback,没有使用Observer作为回调。
public abstract class FooCallback {
public abstract void onStarted();
public abstract void onStopped();
}
public void registerFooCallback(@NonNull FooCallback callback) {}
public void unregisterFooCallback(@NonNull FooCallback callback) {}
如果上述注册方法没有在明确的线程中时,则需要在注册的时候包含Executor参数,如果不加的话,默认在主线程中回调。
我的register方法没有添加Executor,则编译报错:
Registration methods should have overload that accepts delivery Executor: `registerFooCallback` [ExecutorRegistration]
因此,改为下边的注册方法:
public void registerFooCallback( @NonNull @CallbackExecutor Executor executor,
@NonNull FooCallback callback)
//unregister方法不需要添加Executor
public void unregisterFooCallback(@NonNull FooCallback callback) {}
3.2 避免使用枚举类enum
在Framework层使用enum会报错:Enums are discouraged in Android APIs [Enum],因此一般都用@intDef代替,使用新的注解表示。