Skip to content

Commit

Permalink
初步增加安卓相机API;
Browse files Browse the repository at this point in the history
实现数组类型的自动关联;
更新依赖项;
发布0.3.5版本。
  • Loading branch information
SmileSky committed Nov 21, 2024
1 parent c8fb71f commit 634ae13
Show file tree
Hide file tree
Showing 20 changed files with 4,340 additions and 94 deletions.
12 changes: 8 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ authors = ["mzdk100 <[email protected]>"]
description = "用于Rust的Android API的高级封装"
keywords = ["android", "api", "sdk", "jni", "java"]
license = "Apache-2.0"
version = "0.3.5"
version = "0.3.6"
edition = "2021"
readme = "README.md"
repository = "https://gitcode.net/mzdk100/droid-wrap.git"
Expand All @@ -30,10 +30,13 @@ rustdoc-args = ["--cfg", "docsrs", "--generate-link-to-definition"]
android = ["java_lang"]
android_app = ["android", "android_view", "java_lang"]
android_content = ["android", "android_media", "android_os", "java_lang", "java_io"]
android_hardware = ["android"]
android_content_pm = []
android_graphics = ["android"]
android_hardware = ["android", "android_graphics", "android_renderscript"]
android_hardware_vibrator = ["android_hardware"]
android_media = ["android"]
android_os = ["android", "android_hardware_vibrator", "java_lang"]
android_renderscript = ["android"]
android_speech = ["android"]
android_speech_tts = ["android_speech", "android_os", "java_lang"]
android_text = ["android", "java_lang"]
Expand All @@ -51,6 +54,7 @@ java_nio_file = ["java_nio"]
test = []
test_android_app = ["android_app", "android_widget"]
test_android_content = ["android_content"]
test_android_hardware = ["android_app", "android_content_pm"]
test_android_os = ["android_app", "android_content", "android_os", "java_lang"]
test_android_text = ["android_text"]
test_android_view = ["android_content", "android_view"]
Expand All @@ -67,11 +71,11 @@ test_java_nio = ["java_nio"]
[dependencies]

[dependencies.droid-wrap-utils]
version = "0.3.4"
version = "0.3.6"
path = "utils"

[dependencies.droid-wrap-derive]
version = "0.3.5"
version = "0.3.6"
path="derive"

[workspace]
Expand Down
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,26 @@
注意:我们不使用javac来编译生成java字节码,所以无须使用完整的JDK环境,仅使用JRE(Java 运行时)即可。
2. 安装apk打包工具
```shell
cargo install cargo-apk
cargo install cargo-apk2
```
3. 运行示例
```shell
git clone https://gitcode.net/mzdk100/droid-wrap.git
cd droid-wrap
cargo apk run -p droid-wrap-example --example activity-example
cargo apk run -p droid-wrap-example --example java-example
cargo apk2 run -p droid-wrap-example --example activity-example
cargo apk2 run -p droid-wrap-example --example java-example
```
4. 运行测试
```shell
cargo apk run -p droid-wrap-test --all-features
cargo apk2 run -p droid-wrap-test --all-features
```

如需了解更多信息,请查看example目录中的代码示例。

### 关于构建工具

cargo-apk目前已经被标记为弃用状态,但不得不承认他在rust生态中是最好用的apk打包工具,因此我们尝试重新实现类似的工具[cargo-aapt2](aapt2/README.md)
[cargo-apk2](https://github.com/mzdk100/cargo-apk2)是一个更加轻量级的安卓apk打包工具,他从已经弃用的[cargo-apk](https://github.com/rust-mobile/cargo-apk)fork而来,cargo-apk2将持续维护,可放心使用。
同时本项目中提供了一个[cargo-aapt2](aapt2/README.md)的cargo扩展程序,如果您对打包apk有更高的需求,可以使用此扩展。


## 分类
Expand All @@ -77,6 +78,12 @@ cargo-apk目前已经被标记为弃用状态,但不得不承认他在rust生
4. android.content.ComponentName;
5. android.content.ComponentName_WithComponentName;

### 安卓硬件(android_hardware)

1. android.hardware.Camera;
2. android.hardware.vibrator.Effect;
3. android.hardware.vibrator.EffectStrength;

### 安卓系统(android_os)

1. android.os.Bundle;
Expand Down Expand Up @@ -121,6 +128,9 @@ android.view.View的API等(包括点击监听器的实现)。
14. android.view.ViewParent;
15. android.view.View_OnKeyListener;
16. android.view.Window;
17. android.view.ContextThemeWrapper;
18. android.view.SurfaceHolder;
19. android.view.Surface;

### 安卓小部件(android_widget)

Expand Down
4 changes: 2 additions & 2 deletions derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ repository.workspace = true

[dependencies]
heck = "0.5.0"
proc-macro2 = "1.0.88"
proc-macro2 = "1.0.91"
quote = "1.0.37"

[dependencies.syn]
features = ["full"]
version = "2.0.82"
version = "2.0.89"

[lib]
proc-macro = true
17 changes: 10 additions & 7 deletions derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ use syn::{
TypeParamBound, Visibility,
};

use crate::utils::{
get_object_return_value_token, get_result_token, get_return_value_token,
parse_function_signature, ClassMetadata, InterfaceMetadata, MethodMetadata,
};
use crate::utils::{get_object_return_value_token, get_result_token, get_return_value_token, parse_function_signature, ClassMetadata, FieldMetadata, InterfaceMetadata, MethodMetadata};

//noinspection SpellCheckingInspection
/// 定义java class,将此属性标记在struct上,可以自动实现操作java对象的必要功能。
Expand Down Expand Up @@ -305,7 +302,7 @@ pub fn java_method(attrs: TokenStream, input: TokenStream) -> TokenStream {
let (self_, _, arg_types_sig, fmt, arg_values, ret_type) =
parse_function_signature(&sig, &type_bounds);
let (ret_value, ret_type_sig, is_result_type) =
get_return_value_token(&ret_type, &sig.generics, &type_bounds);
get_return_value_token(&ret_type, &sig.generics, &type_bounds, &None);

let ret_value = get_result_token(is_result_type, &ret_value);

Expand Down Expand Up @@ -451,6 +448,10 @@ pub fn java_interface(attrs: TokenStream, input: TokenStream) -> TokenStream {
#[doc = concat!("L", #cls, ";")]
const OBJECT_SIG: &'static str = concat!("L", #cls, ";");
}));
item.items.push(TraitItem::Verbatim(quote! {
/// 数组维度
const DIM: u8 = 0;
}));
let stream = quote! {
#item
};
Expand Down Expand Up @@ -638,7 +639,9 @@ pub fn java_implement(attrs: TokenStream, input: TokenStream) -> TokenStream {
/// }
/// ```
#[proc_macro_attribute]
pub fn java_field(_: TokenStream, input: TokenStream) -> TokenStream {
pub fn java_field(attrs: TokenStream, input: TokenStream) -> TokenStream {
let attrs: FieldMetadata = parse2(Into::<TokenStream2>::into(attrs)).unwrap();
let default_value = attrs.default_value.clone();
let item = parse_macro_input!(input as ItemFn);
let attrs = item.attrs.clone();
let stmts = item.block.stmts.clone();
Expand Down Expand Up @@ -670,7 +673,7 @@ pub fn java_field(_: TokenStream, input: TokenStream) -> TokenStream {
}

let (ret_value, ret_type_sig, is_result_type) =
get_return_value_token(&ret_type, &sig.generics, &vec![]);
get_return_value_token(&ret_type, &sig.generics, &vec![], &default_value);

let ret_value = get_result_token(is_result_type, &ret_value);

Expand Down
34 changes: 31 additions & 3 deletions derive/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ impl Parse for ClassMetadata {
}
}

pub(crate) struct FieldMetadata {
pub(crate) default_value: Option<Expr>,
}

impl Parse for FieldMetadata {
fn parse(input: ParseStream) -> syn::Result<Self> {
let attrs = Punctuated::<MetaNameValue, Token![,]>::parse_terminated(input)?;
let default_value = match attrs.iter().find(|i| i.path.is_ident("default_value")) {
None => None,
Some(v) => Some(v.value.clone()),
};

Ok(Self { default_value })
}
}

pub(crate) struct InterfaceMetadata {
pub(crate) interface_name: Expr,
}
Expand Down Expand Up @@ -150,10 +166,17 @@ fn get_type_descriptor_token(
{
let tt = it.1.clone();
quote! {<#ty as #tt>}
} else if !ty_str.starts_with(|c: char| c.is_alphabetic() || c == '&') {
// 如果不是有效标识符开头的类型(也不是引用类型)则需要使用`<...>`
quote! {<&#ty>}
} else {
ty.clone()
};
quote! {#ty::OBJECT_SIG}
if ty_str.starts_with("&") {
quote! {&("[".repeat(*#ty::DIM as _) + #ty::OBJECT_SIG)}
} else {
quote! {&("[".repeat(#ty::DIM as _) + #ty::OBJECT_SIG)}
}
}
}

Expand All @@ -168,7 +191,7 @@ pub(crate) fn parse_function_signature(
TokenStream,
TokenStream,
) {
let mut self_: Option<SelfValue> = None;
let mut self_ = None;
let mut arg_types = Vec::new();
let mut arg_types_sig = TokenStream::new();
let mut arg_values = Punctuated::<Expr, Token![,]>::new();
Expand Down Expand Up @@ -259,9 +282,14 @@ pub(crate) fn get_return_value_token(
ret_type: &TokenStream,
generics: &Generics,
type_bounds: &Vec<(TokenStream, TokenStream)>,
default_value: &Option<Expr>,
) -> (TokenStream, TokenStream, bool) {
let (unwrapped_ty, ty) = unwrap_type(ret_type);
let ret_type_sig = get_type_descriptor_token(&unwrapped_ty, generics, &type_bounds);
let unwrap_value = match default_value {
None => quote! {unwrap()},
Some(v) => quote! {unwrap_or(#v)},
};

if ret_type_sig.to_string().contains("OBJECT_SIG") {
let (ret_value, is_result_type) = get_object_return_value_token(&ret_type);
Expand Down Expand Up @@ -325,7 +353,7 @@ pub(crate) fn get_return_value_token(
is_result_type = true;
opt
} else {
quote! {#opt.unwrap()}
quote! {#opt.#unwrap_value}
};
(opt, ret_type_sig, is_result_type)
}
Expand Down
1 change: 1 addition & 0 deletions example/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ version.workspace = true
edition.workspace = true
readme.workspace = true
repository.workspace = true
publish = false

[package.metadata.android.sdk]
min_sdk_version = 26
Expand Down
8 changes: 3 additions & 5 deletions example/src/activity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use droid_wrap::{
android::{
app::Activity,
content::Context,
view::{
ViewGroup_LayoutParams, ViewManager, WindowManagerImpl, WindowManager_LayoutParams,
},
Expand All @@ -35,12 +34,11 @@ fn main() {
act.set_title(&cs);
dbg!(&act);
let act = Arc::new(act);
let context: Context = act.as_ref().into();
let text_view = TextView::new(&context);
let text_view = TextView::new(act.as_ref());
text_view.set_text(Some(
"你好,这是一个用Rust构建的安卓示例。".to_char_sequence::<CharSequenceImpl>(),
));
let edit = EditText::new(&context);
let edit = EditText::new(act.as_ref());

let editor_listener = TextView_OnEditorActionListenerImpl::from_fn(|_, _, _| true);
edit.set_on_editor_action_listener(editor_listener.as_ref());
Expand All @@ -55,7 +53,7 @@ fn main() {
ViewGroup_LayoutParams::MATCH_PARENT,
1.0,
);
let layout = LinearLayout::new(&context);
let layout = LinearLayout::new(act2.as_ref());
layout.set_orientation(LinearLayout::VERTICAL);
// layout.add_view(&text_view);
layout.set_content_description(Some("容器".to_char_sequence::<CharSequenceImpl>()));
Expand Down
Loading

0 comments on commit 634ae13

Please sign in to comment.