(一百八十九)Android Jetpack 学习(一)

前言:老大让学习点新的东西分享一下,本来看了WiFi的电量统计,看到最后感觉挺没意思的,然后就翻bos直聘看有什么新技术要求的,看到flutter,Jetpack、react native。。。Jetpack这个比较新,学习下Jetpack

参考:

https://developer.android.google.cn/jetpack

https://developer.android.google.cn/jetpack/docs/getting-started/

下面这个是官方整理的应用开发指导?

https://developer.android.google.cn/guide

1. 简介

Jetpack 是一套库、工具和指南,可帮助开发者更轻松地编写优质应用。这些组件可帮助您遵循最佳做法、让您摆脱编写样板代码的工作并简化复杂任务,以便您将精力集中放在所需的代码上。

Jetpack 包含与平台 API 解除捆绑的 androidx.* 软件包库。这意味着,它可以提供向后兼容性,且比 Android 平台的更新频率更高,以此确保您始终可以获取最新且最好的 Jetpack 组件版本。

总体宣传了三大优势

2.Android Jetpack 组件

Android Jetpack 组件是库的集合,这些库是为协同工作而构建的,不过也可以单独采用,同时利用 Kotlin 语言功能帮助您提高工作效率。可全部使用,也可混合搭配!

主要分为四大部分组件

详细列出如下,用红色线条分割开来对应上面四大组件,Google官网可点击查看详细

3. Android Jetpack 使用入门

Jetpack 包含一系列 Android 库,它们都采用最佳做法并在 Android 应用中提供向后兼容性。

Jetpack 应用架构指南概述了构建 Android 应用时要考虑的最佳做法和推荐架构。

下文介绍了如何开始使用 Jetpack 组件。

3.1 在应用中使用 Jetpack 库

所有 Jetpack 组件都可在 Google Maven 代码库中找到。

打开您的项目的 build.gradle 文件并添加 google() 代码库,如下所示:

    allprojects {
        repositories {
            google()
            jcenter()
        }
    }
    

然后,您可以添加 Jetpack 组件,例如作为 Lifecycles 库的一部分的 LiveData 和 ViewModel 等架构组件,如下所示:

    dependencies {
        def lifecycle_version = "2.0.0"
        implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
        // Optional : Kotlin extension (https://d.android.com/kotlin/ktx)
        implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
        ...
    }
    

许多 Jetpack 库还提供 Android KTX 扩展程序,如上面的 lifecycle-viewmodel-ktx 所示。KTX 扩展程序以基于 Java 的 API 为基础,充分利用了 Kotlin 特有的语言功能。

如需了解新的 Jetpack 库版本,请查看版本页面。

基于 Kotlin 以及基于 Java 的 API 参考页面适用于所有 Jetpack 库。

有点不妙,google()这个仓还被墙吗?动手试下

3.1.1 Unable to resolve dependency

Could not resolve com.android.support:appcompat-v7:29

修改了最低的Android 版本为p,然后随便创建一个module然后就报错了。。。

方案一:

参考https://blog.csdn.net/afireswallow/article/details/91129831

感觉解决的方式不大对,改了依赖的版本,走偏门的不靠谱

方案二:

https://blog.csdn.net/Camille05/article/details/96697638

这个感觉靠谱,我的sdk tools版本和platform version明显错位了

之后右键module弹出module Settings改变buildToolsVersion

buildToolsVersion '28.0.3'

这时发现29是Q的版本,不知道什么时候选错了,都改成28还是报错,算了,还是先按方案一来吧

待续

ERROR: Unable to resolve dependency for ':demo_189_jetpack@debug/compileClasspath': Could not resolve androidx.lifecycle:lifecycle-extensions:2.0.0.
Show Details
Affected Modules: demo_189_jetpack


ERROR: Unable to resolve dependency for ':demo_189_jetpack@debug/compileClasspath': Could not resolve androidx.lifecycle:lifecycle-viewmodel-ktx:2.0.0.
Show Details
Affected Modules: demo_189_jetpack


ERROR: Unable to resolve dependency for ':demo_189_jetpack@debugAndroidTest/compileClasspath': Could not resolve androidx.lifecycle:lifecycle-extensions:2.0.0.
Show Details
Affected Modules: demo_189_jetpack

导入入门的依赖,恩,意料之中resolve dependency失败,开发环境真是。。。。。。

待续

思路:

https://blog.csdn.net/weixin_40849588/article/details/86559842

https://blog.csdn.net/weixin_40849588/article/details/90575618

4. 组件体验

4.1 lifecycle

https://developer.android.google.cn/topic/libraries/architecture/lifecycle

Lifecycle-aware components perform actions in response to a change in the lifecycle status of another component, such as activities and fragments. These components help you produce better-organized, and often lighter-weight code, that is easier to maintain.

A common pattern is to implement the actions of the dependent components in the lifecycle methods of activities and fragments. However, this pattern leads to a poor organization of the code and to the proliferation of errors. By using lifecycle-aware components, you can move the code of dependent components out of the lifecycle methods and into the components themselves.

我们之前写和activity fragment生命周期强相关的代码的时候,比如注册广播,总是会在生命周期了罗列很多代码,让代码结构变得繁杂后续难以维护,现在有个lifecycle可以优化这种场景使用。

Moreover, there's no guarantee that the component starts before the activity or fragment is stopped. This is especially true if we need to perform a long-running operation, such as some configuration check in onStart(). This can cause a race condition where the onStop() method finishes before the onStart(), keeping the component alive longer than it's needed.

另外有时候我们在生命周期里执行耗时操作的时候activity或者fragment被干掉了就会有问题。

这个让我想到了Settings,WiFi里的WifiTracker就是这么用的,之前梳理过

(一百三十九)Android P 结合WifiSettings学习WifiTracker的生命周期

A common use case is to avoid invoking certain callbacks if the Lifecycle isn't in a good state right now. For example, if the callback runs a fragment transaction after the activity state is saved, it would trigger a crash, so we would never want to invoke that callback.

To make this use case easy, the Lifecycle class allows other objects to query the current state.

KOTLINJAVA

class MyLocationListener implements LifecycleObserver {
    private boolean enabled = false;
    public MyLocationListener(Context context, Lifecycle lifecycle, Callback callback) {
       ...
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void start() {
        if (enabled) {
           // connect
        }
    }

    public void enable() {
        enabled = true;
        if (lifecycle.getCurrentState().isAtLeast(STARTED)) {
            // connect if not connected
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void stop() {
        // disconnect if connected
    }
}

With this implementation, our LocationListener class is completely lifecycle-aware. If we need to use our LocationListener from another activity or fragment, we just need to initialize it. All of the setup and teardown operations are managed by the class itself.

还有个比较好的是实现LifecycleObserver的类通过使用lifecycle.getCurrentState可以完全知晓当前activity或者fragment当前的状态?

getCurrentState是public的,状态是枚举类型

    public enum Event {
        /**
         * Constant for onCreate event of the {@link LifecycleOwner}.
         */
        ON_CREATE,
        /**
         * Constant for onStart event of the {@link LifecycleOwner}.
         */
        ON_START,
        /**
         * Constant for onResume event of the {@link LifecycleOwner}.
         */
        ON_RESUME,
        /**
         * Constant for onPause event of the {@link LifecycleOwner}.
         */
        ON_PAUSE,
        /**
         * Constant for onStop event of the {@link LifecycleOwner}.
         */
        ON_STOP,
        /**
         * Constant for onDestroy event of the {@link LifecycleOwner}.
         */
        ON_DESTROY,
        /**
         * An {@link Event Event} constant that can be used to match all events.
         */
        ON_ANY
    }

具体api可以参考

http://androidxref.com/9.0.0_r3/xref/frameworks/support/lifecycle/common/src/main/java/androidx/lifecycle/Lifecycle.java

Fragments and Activities in Support Library 26.1.0 and later already implement the LifecycleOwner interface.

搜了下Android P的源码里已经继承了,所以WifiSettings可以直接用getLifecycle

实践指导

Best practices for lifecycle-aware components

  • Keep your UI controllers (activities and fragments) as lean as possible. They should not try to acquire their own data; instead, use a ViewModel to do that, and observe a LiveData object to reflect the changes back to the views.
  • Try to write data-driven UIs where your UI controller’s responsibility is to update the views as data changes, or notify user actions back to the ViewModel.
  • Put your data logic in your ViewModel class. ViewModel should serve as the connector between your UI controller and the rest of your app. Be careful though, it isn't ViewModel's responsibility to fetch data (for example, from a network). Instead, ViewModel should call the appropriate component to fetch the data, then provide the result back to the UI controller.
  • Use Data Binding to maintain a clean interface between your views and the UI controller. This allows you to make your views more declarative and minimize the update code you need to write in your activities and fragments. If you prefer to do this in the Java programming language, use a library like Butter Knife to avoid boilerplate code and have a better abstraction.
  • If your UI is complex, consider creating a presenter class to handle UI modifications. This might be a laborious task, but it can make your UI components easier to test.
  • Avoid referencing a View or Activity context in your ViewModel. If the ViewModel outlives the activity (in case of configuration changes), your activity leaks and isn't properly disposed by the garbage collector.
  • Use Kotlin coroutines to manage long-running tasks and other operations that can run asynchronously.

例子

Use cases for lifecycle-aware components

Lifecycle-aware components can make it much easier for you to manage lifecycles in a variety of cases. A few examples are:

  • Switching between coarse and fine-grained location updates. Use lifecycle-aware components to enable fine-grained location updates while your location app is visible and switch to coarse-grained updates when the app is in the background. LiveData, a lifecycle-aware component, allows your app to automatically update the UI when your user changes locations.
  • Stopping and starting video buffering. Use lifecycle-aware components to start video buffering as soon as possible, but defer playback until app is fully started. You can also use lifecycle-aware components to terminate buffering when your app is destroyed.
  • Starting and stopping network connectivity. Use lifecycle-aware components to enable live updating (streaming) of network data while an app is in the foreground and also to automatically pause when the app goes into the background.
  • Pausing and resuming animated drawables. Use lifecycle-aware components to handle pausing animated drawables when while app is in the background and resume drawables after the app is in the foreground.

高低精度定位、视频缓冲、网络连接和动画都可以使用lifecycle-aware

例外

Handling on stop events

When a Lifecycle belongs to an AppCompatActivity or Fragment, the Lifecycle's state changes to CREATEDand the ON_STOP event is dispatched when the AppCompatActivity or Fragment's onSaveInstanceState() is called.

When a Fragment or AppCompatActivity's state is saved via onSaveInstanceState(), it's UI is considered immutable until ON_START is called. Trying to modify the UI after the state is saved is likely to cause inconsistencies in the navigation state of your application which is why FragmentManager throws an exception if the app runs aFragmentTransaction after state is saved. See commit() for details.

LiveData prevents this edge case out of the box by refraining from calling its observer if the observer's associated Lifecycle isn't at least STARTED. Behind the scenes, it calls isAtLeast() before deciding to invoke its observer.

Unfortunately, AppCompatActivity's onStop() method is called after onSaveInstanceState(), which leaves a gap where UI state changes are not allowed but the Lifecycle has not yet been moved to the CREATED state.

To prevent this issue, the Lifecycle class in version beta2 and lower mark the state as CREATED without dispatching the event so that any code that checks the current state gets the real value even though the event isn't dispatched until onStop() is called by the system.

Unfortunately, this solution has two major problems:

  • On API level 23 and lower, the Android system actually saves the state of an activity even if it is partially covered by another activity. In other words, the Android system calls onSaveInstanceState() but it doesn't necessarily call onStop(). This creates a potentially long interval where the observer still thinks that the lifecycle is active even though its UI state can't be modified.
  • Any class that wants to expose a similar behavior to the LiveData class has to implement the workaround provided by Lifecycle version beta 2 and lower.

Note: To make this flow simpler and provide better compatibility with older versions, starting at version 1.0.0-rc1Lifecycle objects are marked as CREATED and ON_STOP is dispatched when onSaveInstanceState() is called without waiting for a call to the onStop() method. This is unlikely to impact your code but it is something you need to be aware of as it doesn't match the call order in the Activity class in API level 26 and lower.

由于onSavedInstanceState之后不能改变UI,但是这时候activity或者fragment的生命周期还没走到onStop,这时候就会有bug,这里采用里一个workround的方案,当onSavedInstanceState调用的时候infecycle就被标记为create,on_stop事件就被传达出去。

更多资源学习

Additional resources

To learn more about handling lifecycles with lifecycle-aware components, consult the following additional resources.

Samples

Codelabs

Blogs

发布了198 篇原创文章 · 获赞 65 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/sinat_20059415/article/details/102885550