介绍Nibel:面向基于Fragment的应用的导航库,支持无缝使用Jetpack Compose

186 篇文章 15 订阅
订阅专栏
26 篇文章 2 订阅
订阅专栏

图片

Nibel简介

介绍Nibel:面向基于Fragment的应用的导航库,支持在依赖于Fragment的Android应用中无缝使用Jetpack Compose。 我们构建Nibel时的目标是,为团队创建新功能时提供真正的Jetpack Compose体验,同时自动保持与代码库的兼容性。通过利用Kotlin符号处理器(KSP)的强大功能,Nibel提供了一种统一且类型安全的方式来在以下导航场景之间进行页面导航:

  1. 1. Fragment → Compose

  2. 2. Compose → Compose

  3. 3. Compose → Fragment

Nibel支持单模块和多模块导航,特别适用于在功能模块之间进行导航,这些功能模块之间不直接依赖于彼此。

在本文中,您将了解如何在项目中开始使用Nibel,以及Jetpack Compose的常见采用场景和Nibel提供的自定义选项。

如何使用?

以下是在项目中使用Nibel开始采用Jetpack Compose的基本步骤:

  1. 1. 声明一个屏幕。要开始使用Nibel,只需使用@UiEntry注解标记您的Compose函数。这将生成一个{ComposableName}Entry类,用于导航到此屏幕。

@UiEntry(type = ImplementationType.Fragment)
@Composable
fun FooScreen(
  navigator: NavigationController // optional param
) { ... }

对于带有参数的屏幕,只需在注解中传递您的Parcelable args类。

@UiEntry(
  type = ImplementationType.Composable,
  args = BarScreenArgs::class
)
@Composable
fun BarScreen(
  args: BarScreenArgs, // optional param
  navigator: NavigationController // optional param
) { ... }

稍后我们将详细查看ImplementationType

  1. 1. 在Compose屏幕之间进行导航。使用NavigationController,可以在标记的Compose屏幕之间进行导航。只需使用navigateTo函数,并将生成的entry实例作为参数传递。

val args = BarScreenArgs(...)
navigator.navigateTo(BarScreenEntry.newInstance(args))
  1. 1. 导航到Fragment。同样,可以使用NavigationController从Compose屏幕导航到旧的Fragment。

class BazFragment : Fragment() { ... }

将Fragment实例包装为FragmentEntry,并将其传递给navigateTo函数。

val fragment = BazFragment()
navigator.navigateTo(FragmentEntry(fragment))
  1. 1. 从Fragment导航。标记的Compose屏幕对于非Compose世界来说表现得像Fragment。将生成的entry类视为Fragment,并使用transaction进行导航。

class QuxFragment : Fragment() {
  ...
  requireActivity().supportFragmentManager.commit {
    replace(android.R.id.content, FooScreenEntry.newInstance().fragment)
  }
}

多模块导航

在多模块应用中,通常会存在不直接依赖于彼此的功能模块。在这种情况下,无法直接获取另一个功能模块中生成的entry类的引用。

Nibel提供了一种简单的、类型安全的多模块导航方式,使用"目标"的概念。目标是一个简单的数据类型,用作导航意图,并位于一个单独的模块中,可供其他功能模块使用。

图片

每个目标与一个屏幕相关联,因此在需要导航时,使用目标的实例来到达目标屏幕。

图片

在应用中无需有一个单一的导航模块,可以有多个导航模块。然而,关键要求是目标类型对源屏幕和目标屏幕都可用。

  1. 1. 声明一个目标。最基本的目标是实现DestinationWithNoArgs的对象,并在一个单独的导航模块中声明,供其他功能模块使用。

// :navigation模块
object FooScreenDestination : DestinationWithNoArgs

如果需要带有参数的屏幕,请继承DestinationWithArgs

// :feature模块,依赖于:navigation模块
data class BarScreenDestination(
  override val args: BarScreenArgs // Parcelable args
) : DestinationWithArgs<BarScreenArgs>
  1. 1. 将目标与屏幕关联。每个目标应该使用@UiExternalEntry注解与一个屏幕相关联,放在Compose函数上。

@UiExternalEntry(
  type = ImplementationType.Fragment,
  destination = BarScreenDestination::class
)
@Composable
fun BarScreen(
  args: BarScreenArgs, // optional param
  navigator: NavigationController // optional param
) { ... }

如果需要从Compose导航到旧的Fragment,则应将@LegacyExternalEntry应用于Fragment。

@LegacyExternalEntry(destination = BasScreenDestination::class)
class BazScreenFragment : Fragment() { ... }
  1. 1. 导航到目标。使用NavigationController导航到目标。

val args = BarScreenArgs(...)
navigator.navigateTo(BarScreenDestination(args))

@UiScreenEntry包含@UiEntry的所有功能,因此,如果您直接引用了生成的entry类,以下代码也适用于同一屏幕。

val args = BarScreenArgs(...)
navigator.navigateTo(BarScreenEntry.newInstance(args))
  1. 1. 从Fragment导航。最后,如果需要从旧的Fragment导航到Compose屏幕,应使用目标来获取Fragment实例并执行事务。

class QuxScreenFragment : Fragment() {
  ...
  requireActivity().supportFragmentManager.commit {
    val entry = Nibel.newFragmentEntry(BarScreenDestination)!!
    replace(android.R.id.content, entry.fragment)
  }
}

Compose函数参数

使用@UiEntry@UiExternalEntry注解的Compose函数可以有任意数量的参数,只要它们有默认值。

@UiEntry(type = ImplementationType.Fragment)
fun FooScreen(viewModel: FooViewModel = viewModel()) { ... }

此外,还有一些特殊类型的参数不需要默认值,因为Nibel可以找出如何提供相应的实例。这些特殊类型的参数包括NavigationController、ImplementationType,以及与@UiEntry注解或目标类型中相同类型的args。

@UiEntry(
  type = ImplementationType.Composable, 
  args = BarArgs::class
)
fun BarScreen(
  args: BarArgs,
  navigator: NavigationController,
  type: ImplementationType
) { ... }

如果参数类型不匹配,将会抛出编译时错误。

另外,上述值也可以作为组合局部变量获取。

@UiEntry(
  type = ImplementationType.Composable, 
  args = BarArgs::class
)
fun BarScreen() {
  val args = LocalArgs.current as BarArgs
  val navigator = LocalNavigationController.current
  val type = LocalImplementationType.current
}

常见用法场景

根据目标屏幕的注解中指定的ImplementationType,生成的条目类型有所不同。每种类型都适用于特定的场景,可能是以下之一:

  1. 1. Fragment - 生成的条目是一个使用带注解的Compose函数作为其内容的Fragment。它使得Compose屏幕对其他Fragment可见,对于fragment → compose导航场景至关重要。

  2. 2. Composable - 生成一个小的包装类覆盖Compose函数。通常在compose → composecompose → fragment导航场景中使用,后者使用这种实现类型进行标记。

通常,将新的Jetpack Compose屏幕添加到现有代码库有几种常见场景。

场景1 - 新功能

最简单的情况是在单独的模块中创建全新的功能。在这种情况下,该功能的所有屏幕都使用Jetpack Compose。

图片

功能的第一个屏幕作为外部入口,允许从其他模块进入该功能。它必须标记为ImplementationType.Fragment。这将确保它在非Compose代码中显示为一个Fragment,因此,轻松地从旧Fragment导航到这个新功能。

功能中的所有后续屏幕应该使用ImplementationType.Composable。这将提高性能,因为不会生成Fragment,从而导致每个屏幕的类分配更少。

在某些情况下,您可能需要从新功能返回到依赖于Fragment的旧功能。您只需要用@LegacyExternalEntry注解目标Fragment,并通过NavigationController使用其关联的目标进行导航。

图片

场景2 - 扩展现有功能

另一种情况是需要在现有功能中插入一系列新的连续屏幕。在这种情况下,即使这些屏幕位于Fragment流程的中间,它们也可以是Compose屏幕。

图片

关键规则仍然相同。第一个Compose屏幕应该标记为ImplementationType.Fragment,而所有后续屏幕应该使用ImplementationType.Composable

场景3 - 独立屏幕

第三种情况可能在采用Jetpack Compose的早期阶段最常见。在这种情况下,独立的Compose屏幕放置在旧Fragment流程的中间。

图片

在这种情况下,您只需要用ImplementationType.Fragment注解Compose屏幕,并在Compose代码之外将它们视为Fragment。

自定义设置

Nibel提供了各种自定义选项,以便根据特定项目的需求进行适应。

在继续本节之前,建议查阅我们之前的故事,其中更详细地介绍了Nibel的内部组件以及其背后实现的思路。

应用主题

对于每个用ImplementationType.Fragment注解的屏幕,Nibel会生成一个entry类,它是一个继承自ComposableFragment的fragment。在使用Jetpack Compose与fragments时,所有的可组合UI都设置在onCreateView中。这意味着对于每个新的fragment,都必须显式地应用一个主题。

// 生成的fragment的基类
// (位于nibel-runtime库的一部分)
abstract class ComposableFragment : Fragment() {

  @Composable
  abstract fun ComposableContent()

  override fun onCreateView(
    ...
  ) = ComposeView(requireContext()).apply {
    setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
    setContent {
      AppTheme { // 在这里应用主题
        ...
      }
    }
  }
}

由于这是第三方库的基类,无法直接应用特定应用的自定义主题。

要应用主题,您可以实现一个RootDelegate,这将是一个只有一个简单的组合函数的类。这个函数会在每个用ImplementationType.Fragment注解的屏幕的根部调用。

object CustomRootContent : RootDelegate {

  @Composable
  override fun Content(content: @Composable () -> Unit) {
    AppTheme { // 应用自定义主题
      content()
    }
  }
}

不要忘记调用content函数,以继续UI的构建。

然后在配置Nibel时,只需应用CustomRootContent

Nibel.configure(rootDelegate = CustomRootContent)

导航规范

正如上面所述,NavigationController用于在屏幕之间进行导航。然而,navigateTo函数也提供了自定义的空间。

abstract class NavigationController(...) {
  ...

  fun navigateTo(
    entry: Entry,
    fragmentSpec: FragmentSpec<*>, // fragment导航规范
    composeSpec: ComposeSpec<*> // compose导航规范
  )
}

正如我们已经知道的,Nibel允许在各种情况下在fragment和compose屏幕之间导航。当从可组合函数导航到新屏幕时,Nibel在内部使用不同的工具进行导航,具体取决于目标屏幕。

如果下一个屏幕是一个fragment或者用ImplementationType.Fragment注解的可组合函数,将自动执行一个fragment事务。 如果下一个屏幕是用ImplementationType.Composable注解的可组合函数,Nibel将隐式地使用compose导航库进行导航。 在任何时候,您都可以在注解中切换ImplementationType,代码仍然可以编译。然而,Nibel将使用不同的底层工具进行导航。FragmentSpec用于在底层进行fragment之间的导航,而ComposeSpec用于直接导航可组合函数之间的导航,也是隐式的。

在进行底层fragment事务时,有时您可能希望更多地控制其细节。例如,使用add vs replace,选择自定义容器id进行事务等等。

每个导航规范的实例都包含如何执行导航的实现细节。因此,可以通过多种方式进行自定义。

例如,在fragment事务中,您可以使用FragmentTransactionSpec的实例,并指定事务的详细信息。

navigator.navigateTo(
  entry = ..., 
  fragmentSpec = FragmentTransactionSpec(
    replace = true,
    addToBackStack = true,
    containerId = R.id.customContainerId
  )
)

如果这还不够,您可以通过编写自定义导航逻辑来完全覆盖其行为。

class CustomTransactionSpec : FragmentTransactionSpec(...) {

  override fun FragmentTransactionContext.navigateTo(entry: FragmentEntry) {
    this.fragmentManager.commit {
      // 自定义fragment事务逻辑
    }
  }
}

然后通过使用CustomTransactionSpec进行导航。

navigator.navigateTo(
  entry = ..., 
  fragmentSpec = CustomTransactionSpec()
)

对于compose规范,底层使用了compose导航库。所有导航目标都动态添加到ComposeNavigationSpec中。您可以在我们之前的帖子中了解有关底层如何使用compose导航库的更多信息。

最后,在配置Nibel时,可以为应用中的所有屏幕设置任何导航规范。

Nibel.configure(
  fragmentSpec = CustomFragmentSpec(),
  composeSPec = CustomComposeSpec()
)

与架构组件的兼容性

现代Android应用使用各种架构组件,例如Hilt、ViewModel等。让我们看看如何将Nibel与它们集成。

您可以将ViewModel声明为可组合函数的参数,并使用hiltViewModel来获取其实例。现在,您可以在一个由Hilt注入的ViewModel和Nibel屏幕的组合中使用它。

@UiEntry(type = Composable, args = FooArgs::class)
@Composable
fun FooScreen(viewModel: FooViewModel = hiltViewModel()) { ... }
@HiltViewModel
class FooViewModel(handle: SavedStateHandle): ViewModel() {
  val args = handle.getNibelArgs<FooArgs>()
}

您可以注意到,屏幕参数自动在ViewModel的SavedStateHandle中可用。

结论

有了Nibel,您可以专注于使用Jetpack Compose为应用程序编写新的产品功能,同时处理代码库的兼容性,尤其是处理fragment方面的问题。

Nibel具有高度可定制性,因此可以应用于各种类型的项目和在采用Jetpack Compose时的导航场景中。

Github

https://github.com/open-turo/nibel/tree/main/sample https://github.com/open-turo/nibel

 转自:介绍Nibel:面向基于Fragment的应用的导航库,支持无缝使用Jetpack Compose

compose混合开发 fragment使用compose
chuyouyinghe的专栏
07-04 803
环境:jdk:11注意:compose是基于kotlin的,所以kotlin的环境就不过多介绍了…将项目升级为7.0+gradle插件也需要升级为7.0+
Android Navigation + Fragment 制作APP主页面导航(步骤
最新发布
2401_84150302的博客
04-08 437
可能这里你会比较陌生,这里的id,等下要在MainActivity中指明的,这里的name指明的是androidx.navigation.fragment.NavHostFragment,这个属性就表明这个fragment指明的就是NavHost,然后它还要添加需要显示的子Fragment,那么就通过navGraph来绑定这个导航图,之前导航图里面不是就有五个Fragment吗?这里我指明了AFragment。上面的也很简单,id表示它在导航图的标识,name指明这个Fragment的路径,包名+类名。
Android进阶宝典—在Compose中跳转Fragment
m0_70748458的博客
04-18 1366
在这种单Activity架构模式下,有一天我们想把MainActivity或者BFragment使用Compose重构,这个时候我们就需要去处理页面跳转事件,即从Compose中跳转到Fragment,处理这种问题的方式有很多,比如: 1. 将要跳转的Fragment修改为Activity,然后在点击事件中startActivity 2. 针对有页面跳转事件的UI采用原生方式编写与Compose混合使用 3. 将要跳转的Fragment包装成Compose页面,构建统一路由
Android navigation组件
prime的博客
11-24 687
lzyprime 博客 (github) 创建时间:2020.11.24 qq及邮箱:2383518170 kotlin & android 笔记 λ: navigation 组件 是 Android Jetpack重要组成部分,推出3年左右,2018谷歌I/O大会也曾介绍过。主要用于组织Fragment,通过Fragment来实现不同内容片段的显示。包括同级之间切换,不同级之间跳转(如 列表item跳详情页),代替以往跳转Activity的方式,推出单Activity模式。 navigati.
android compose混合开发 fragment使用compose
高级开发者进阶ing... QaQ
01-12 5333
前言:今天心血来潮,把已有的项目升级成了compose的,遇到一些坑,记录一下环境:将项目升级为7.0+gradle插件也需要升级为7.0+在对应的app模块中开启compose添加一些compose常用依赖在fragment使用compose另外一种写法 dialog如何使用: 环境: system: macOS android studio: 4.2 gradle:7.0.3 distributionUrl:7.1.1-bin jdk:11 kotlin_version:1.4.23 注意:co
Android实战开发--底部导航Fragment)篇
yunyanchengyu114的博客
01-08 5138
Fragment实现底部导航,Frament中onCreateView详解,控件id详解
Android 底部(简单,简易)导航栏(Fragment
m0_71759815的博客
11-11 3615
底部导航只需要下面的layout布局,然后将其设为水平布局,主要的还是 android:layout_alignParentBottom=
Fragment导航
orchid_sea的博客
12-21 1320
Fragment——导航栏 添加fragment依赖 //Fragment依赖 implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.fragment:fragment:1.3.2' 添加两个空的Fragment java -> New -> Fragment ->BlankFragment 添加菜单布局文件 res -> New -> And
Android Navigation + Fragment 制作APP主页面导航(步骤 + 源码)
晨曦
12-10 6285
运行效果图 Navigation + Fragment制作APP主页面前言正文1. 添加依赖2. 添加导航图总结 前言   我相信你肯定见过这样的App主页面,底部或者顶部有多个按钮,点击之后会切换当前的页面,滑动当前页面也会切换底部按钮,这里我用几个App的主页面来说明一下吧 淘宝 微博 CSDN App 支付宝 可以说绝大部分App都是这种主页面布局模式,当然还有很多,在这里举列子是让你有一个概念而已。 正文   从上面的一些APP主页面,在之前这种页面是通过什么来做的呢?这里有好几种组合:
Android个人学习笔记-底部导航切换Fragment的实现
iceyung的专栏
11-30 6373
前言:虽然经常来CSDN,但是打开自己的博客一看,竟然已经有一年没有更新了,今年刚刚考上计算机研究生,生活也算是一个新的开始,但是作为一个程序员,这可不是一个正常频率,所以接下来的时间还是要保持一定的更新,也算是督促自己继续学习。这篇文章是采用markdown编写的,刚使用没多久,排版不好,敬请谅解。本文主要针对初学者,大牛们请忽略,因为我也是初学者(好几年了还在原地踏步啊!!!)废话太多,下面全是
导航栏切换3-2(Fragment
chensenli的博客
11-06 460
前言 要切换的页面仅有两个,所以直接采用Fragment的显示和隐藏来实现 先看效果图 布局代码(仅贴出主内容代码) &lt;RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="...
Fragment使用Android实现底部导航栏)
Sir.迷航
06-11 6722
  一、布局页面添加 1.添加四个切换页面的布局 (1)四个切换页面的布局(四个页面相同): &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_wid...
android fragment 导航栏,Fragment应用之底部导航栏的实现(一)
weixin_39625337的博客
05-27 796
效果图废话少说,直接上效果图底部导航栏(一).gif最近因为实验室的一个项目要大改,一直没时间来学习学习新的东西写篇博客,不过断断续续花了两周的时间总算是把项目弄好了。这篇博客主要是一周前写的Fragment的后续,都知道现在主流APP基本都会有底部导航栏,比如微信,微博,虎扑什么的无一例外使用了底部导航的设计。本博客所记录的底部导航的实现可能在目前的实际应用中的应用价值不大,这里主要是为了巩固F...
Fragment 实现底部导航栏的简单切换
西门吹雪花
07-28 5320
第一个Android App: 一直想入android这个坑,但一直因为各种原因拖到了现在,今天终于下定决心迈出了第一步。由于公司一直没有android的项目。所以也没有现成的设计和切图,这对于一个刚入坑的人来说真的挺痛苦的,后来实在没办法,就想到了我平时看小说的软件。经历各种办法终于从apk中拿到了切图。下面就开始吧,走起!目标: 不要想多,今天只是实现底部导航栏的点击切换。1. 首先将页
第13天Fragment案例1:底部导航Fragment的hide和show切换(****)
qq_34178710的博客
12-18 749
第13天Fragment案例1:底部导航Fragment的切换(****)Fragment底部切换一.效果二.思路三.代码 Fragment底部切换 一.效果 二.思路 四个radiobutton+4个fragent+动态hide和show指定的Fragment 三.代码 (1)创建4个Fragment,此处省略: (2)activity_main.xml: &amp;amp;lt;LinearLayout x...
使用fragment实现底部导航菜单栏
lz050116的博客
07-07 2702
  在实现这个功能的过程中,走了很多的弯路,也花费了较长的时间,作为一个新手,实现这个功能的过程中,分了几个步骤进行尝试,首先是会使用fragment,这个见另一篇博文:
Andriod :导航栏(Fragment)
qq_40860185的博客
04-21 616
百度搜了一番,不知是软件的版本还是缺少插件的原因,我在建立navigation与FragmentContainerView的联系时,不能像别人一样自动变成Frame,因此只能百度后结合了以下,结合如下: 1.建立navigation 按照上图中所示,建立三个Framement 2.构建导航栏 3.在MainActivity中的XML文件里建立navigation与FragmentContainerView的联系 4.将导航栏导入MainActivity的XML文件中 5.MainActivity类的
BottomNavigationView + fragment底部导航栏简单实现
mercyT的专栏
06-18 2680
BottomNavigationView + fragment实现底部导航
本文给大家介绍Fragment实现底部导航栏,对Fragment实现底部导航栏相关知识感兴趣的朋友一起学习吧
weixin_qwaszx_520的博客
05-26 1106
写这个我们需要写四个fragment的布局,下面只给出其中一个布局的xml.代码如下:&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.an...
写文章

热门文章

  • 能Ping通外网但就是不能打开所有网页的解决办法 69329
  • 使用Filezilla Server配置FTP服务器 61743
  • java在数字前面自动补零的方法 50127
  • 遇到Class path contains multiple SLF4J bindings.该如何解决 47070
  • 安卓6.0系统权限问题android.permission.WRITE_SETTINGS 46047

分类专栏

  • arouter 22篇
  • 协程 88篇
  • jetpack 186篇
  • mvvm 40篇
  • harmony 25篇
  • 音视频方案 25篇
  • 组件化 9篇
  • recycleView 34篇
  • https 56篇
  • http 105篇
  • okhttp 15篇
  • proguard 16篇
  • network 39篇
  • webview 16篇
  • navigation 11篇
  • fragment 26篇
  • retrofit 16篇
  • media 10篇
  • livedata 9篇
  • flutter 82篇
  • dialog 2篇
  • git 8篇
  • 任务调度 3篇
  • junit 1篇
  • javacv 1篇
  • 加固 1篇
  • iconfont 1篇
  • svg 1篇
  • 小程序 1篇
  • 优化 307篇
  • 打包 16篇
  • 文档 7篇
  • 版本管理 66篇
  • 环境配置 71篇
  • 程序设计 327篇
  • 控件 278篇
  • 图形 157篇
  • 自定义控件 92篇
  • java 123篇
  • 课程 28篇
  • 多线程 60篇
  • 组件 254篇
  • 文件 16篇
  • web 31篇
  • 系统层面内容 449篇
  • 52篇
  • 资源操作 72篇
  • Kotlin 179篇
  • 设计模式 26篇
  • 二维码 3篇
  • windows 9篇
  • adb 36篇
  • VMware 7篇
  • mac os 2篇
  • 推送 1篇
  • nio 3篇
  • ipc 26篇
  • database 32篇
  • C 43篇
  • jni 46篇
  • ndk 54篇
  • android studio 149篇
  • openfire 7篇
  • xmpp 10篇
  • IM 12篇
  • smack 4篇
  • 动画 33篇
  • 加解密 4篇
  • framework 82篇
  • 权限 17篇
  • Gradle 218篇
  • Markdown 4篇
  • qt 6篇
  • ffmpeg 19篇
  • Visual Studio 6篇
  • linux 40篇
  • hadoop 28篇
  • nfc 2篇
  • MapReduce 2篇
  • zookeeper 3篇
  • hdfs 5篇
  • hive 3篇
  • hbase 9篇
  • mysql 1篇
  • sqoop 1篇
  • yarn
  • namenode
  • flume 1篇
  • elasticsearch
  • maven 59篇
  • cdh 1篇
  • idea 12篇
  • scala 4篇
  • jdk 30篇
  • spark 2篇
  • 支付 3篇
  • DataNode 1篇
  • aar 10篇
  • shell 1篇
  • 微信小程序 1篇

最新评论

  • 聊聊鸿蒙中 HAR 和 HSP 的使用场景

    狂奔中的毛豆: 为什么在HSP中,preferences没有被初始化,其原因没有讲出来。看出来还是一笔糊涂账

  • rgb转jpg

    moneyxjj: rgb文件格式是什么

  • 2023年App从备案到上架(国内各大应用市场)全过程

    Coder何小二: 还是苹果好,闭环控制,只要app安全就行

  • Android Framework | AOSP源码下载及编译指南(基于Android13)

    随缘的人_: 你这种同步 是下载全部吗?我只想下载某个版本怎么做,

  • 花式读取Android CPU使用率

    没有明天的家伙: 这里好像都是调用adb命令读取的,那普通应用要怎么样才能读取到其他应用的cpu使用率呢。/proc文件系统在hidepid不等于0的情况下普通应用是无法访问/proc/[pid]目录下的文件的,只能访问自己pid的。请问大佬有解决办法吗?

最新文章

  • 【Android】Base64转图片
  • 根据Base64字符流生成相应的二维码
  • Android 34 Arouter适配Gradle7.4.2和8.0
2024
10月 28篇
09月 36篇
08月 53篇
07月 35篇
06月 39篇
05月 22篇
04月 68篇
03月 56篇
02月 56篇
01月 71篇
2023年795篇
2022年623篇
2021年371篇
2020年23篇
2019年19篇
2018年91篇
2017年183篇
2016年179篇
2015年253篇
2014年15篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家浙江季节性商场美陈信阳专业玻璃钢仿铜雕塑临沂玻璃钢小熊雕塑四川园林雕塑玻璃钢海南玻璃钢人物雕塑价格广安玻璃钢仿真水果雕塑定制洮南玻璃钢花盆花器公仔玻璃钢雕塑直销价格玻璃钢动物雕塑价格天津江门玻璃钢动物雕塑铜陵玻璃钢雕塑销售张掖广场玻璃钢雕塑制作北京主题商场美陈厂家供应榆林玻璃钢雕塑厂家价格玻璃钢雕塑厂家特价直销白银人物玻璃钢雕塑龙岩玻璃钢仿铜雕塑厂家商场美陈布置仿真花开封不锈钢玻璃钢雕塑定做厂家龙泉玻璃钢卡通座椅雕塑北京学校人物玻璃钢雕塑福建季节性商场美陈销售公司出口玻璃钢户外雕塑厦门商场美陈创意玻璃钢动物雕塑价格枣庄玻璃钢雕塑制作九龙坡区玻璃钢雕塑招远玻璃钢仿铜雕塑义乌抽象玻璃钢雕塑小品玻璃钢动物雕塑产品介绍香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化